118 lines
2.5 KiB
JavaScript
118 lines
2.5 KiB
JavaScript
|
const root = Symbol("root");
|
||
|
|
||
|
class BinarySearchTreeNode {
|
||
|
constructor (value) {
|
||
|
this.value = value;
|
||
|
this.left = null;
|
||
|
this.right = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class BinarySearchTree {
|
||
|
constructor () {
|
||
|
this[root] = null;
|
||
|
}
|
||
|
|
||
|
add (value) {
|
||
|
const node = new BinarySearchTreeNode(value);
|
||
|
let current = null;
|
||
|
|
||
|
// No items in tree
|
||
|
if (this[root] === null) {
|
||
|
this[root] = node;
|
||
|
} else {
|
||
|
current = this[root];
|
||
|
|
||
|
while (true) {
|
||
|
if (value < current.value) {
|
||
|
// If there's no left, insert
|
||
|
if (current.left === null) {
|
||
|
current.left = node;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
current = current.left;
|
||
|
|
||
|
} else if (value > current.value) {
|
||
|
if (current.right === null) {
|
||
|
current.right = node;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
current = current.right;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
contains (value) {
|
||
|
let found = false;
|
||
|
let current = this[root];
|
||
|
|
||
|
while ( ! found && current !== null) {
|
||
|
if (value < current.value) {
|
||
|
current = current.left;
|
||
|
} else if (value > current.value) {
|
||
|
current = current.right;
|
||
|
} else if (value === current.value) {
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return found;
|
||
|
}
|
||
|
|
||
|
remove (value) {
|
||
|
|
||
|
}
|
||
|
|
||
|
size () {
|
||
|
let length = 0;
|
||
|
|
||
|
this.traverse(() => {
|
||
|
length++;
|
||
|
});
|
||
|
|
||
|
return length;
|
||
|
}
|
||
|
|
||
|
traverse (process) {
|
||
|
const inOrder = (node) => {
|
||
|
if ( ! node) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// traverse the left subtree
|
||
|
if (node.left !== null) {
|
||
|
inOrder(node.left);
|
||
|
}
|
||
|
|
||
|
// handle the current node
|
||
|
process.call(this, node);
|
||
|
|
||
|
// traverse the right subtree
|
||
|
if (node.right !== null) {
|
||
|
inOrder(node.right);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// start with the root
|
||
|
inOrder(this[root]);
|
||
|
}
|
||
|
|
||
|
toArray () {
|
||
|
let result = [];
|
||
|
|
||
|
this.traverse((node) => {
|
||
|
result.push(node.value);
|
||
|
});
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
toString () {
|
||
|
return this.toArray().toString();
|
||
|
}
|
||
|
}
|