Last active
June 19, 2016 16:10
-
-
Save jackson-dean/8e56d31dad9aebbc542db1c31fbfc267 to your computer and use it in GitHub Desktop.
Binary Search Tree (BST) implementation with in-order (ascending and descending), depth-first, and bread-first traversal implementations.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function BinarySearchTree() { | |
this.root = null; | |
this.size = 0; | |
} | |
BinarySearchTree.prototype = { | |
add: function(value) { | |
let node = {value: value}; | |
if (!this.root) { | |
this.root = node; | |
} else { | |
let currentNode = this.root; | |
while(currentNode) { | |
if (currentNode.value > value) { | |
if (!currentNode.leftChild) { | |
currentNode.leftChild = node; | |
break; | |
} else { | |
currentNode = currentNode.leftChild; | |
} | |
} else if (currentNode.value < value) { | |
if (!currentNode.rightChild) { | |
currentNode.rightChild = node; | |
break; | |
} else { | |
currentNode = currentNode.rightChild; | |
} | |
} else { | |
//A simple BST implementation does not | |
//handle duplicates, so return false. | |
return false; | |
} | |
} | |
} | |
this.size++; | |
return true; | |
}, | |
contains: function(value) { | |
let currentNode = this.root; | |
let found = false; | |
while (currentNode) { | |
if (currentNode.value > value) { | |
currentNode = currentNode.leftChild; | |
} else if (currentNode < value) { | |
currenNode = currentNode.rightChild; | |
} else if (currentNode.value === value) { | |
found = true; | |
break; | |
} | |
} | |
return found ? currentNode : false; | |
}, | |
traverse: function(method, callback, startNode) { | |
startNode = startNode || this.root; | |
switch(method) { | |
case 'depth-first': | |
this._depthFirstTraversal(startNode, callback); | |
break; | |
case 'level-order': | |
this._levelOrderTraversal(startNode, callback); | |
break; | |
case 'ascending': | |
this._ascendingTraversal(startNode, callback); | |
break; | |
case 'descending': | |
this._descendingTraversal(startNode, callback); | |
break; | |
} | |
}, | |
_depthFirstTraversal: function(startNode, callback) { | |
let currentNode = startNode; | |
if (!currentNode) { | |
return; | |
} | |
callback(currentNode.value); | |
this._depthFirstTraversal(currentNode.leftChild, callback); | |
this._depthFirstTraversal(currentNode.rightChild, callback); | |
}, | |
_ascendingTraversal: function(startNode, callback) { | |
let currentNode = startNode; | |
if (!currentNode) { | |
return; | |
} | |
this._ascendingTraversal(currentNode.leftChild, callback); | |
callback(currentNode.value); | |
this._ascendingTraversal(currentNode.rightChild, callback); | |
}, | |
_descendingTraversal: function(startNode, callback) { | |
let currentNode = startNode; | |
if (!currentNode) { | |
return; | |
} | |
this._descendingTraversal(currentNode.rightChild, callback); | |
callback(currentNode.value); | |
this._descendingTraversal(currentNode.leftChild, callback); | |
}, | |
_levelOrderTraversal: function(startNode, callback) { | |
if (!startNode) { | |
return values; | |
} | |
let queue = [startNode]; | |
while (queue.length > 0) { | |
let currentNode = queue.shift(); | |
callback(currentNode.value); | |
if (currentNode.leftChild) { | |
queue.push(currentNode.leftChild); | |
} | |
if (currentNode.rightChild) { | |
queue.push(currentNode.rightChild); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment