Skip to content

Instantly share code, notes, and snippets.

@jackson-dean
Last active June 19, 2016 16:10
Show Gist options
  • Save jackson-dean/8e56d31dad9aebbc542db1c31fbfc267 to your computer and use it in GitHub Desktop.
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.
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