[Algorithm] BST Construction
Write a BST class for a Binary Search Tree. The class should support:
- Inserting values with the insert method.
- Removing values with the remove method; this method should only remove the first instance of a given value.
- Searching for values with the contains method.
Note that you can't remove values from a single-node tree. In other words, calling the remove method on a single-node tree should simply not do anything.
Each BST node has an integer value, a left child node, and a right child node. A node is said to be a valid BST node if and only if it satisfies the BST property: its value is strictly greater than the values of every node to its left; its value is less than or equal to the values of every node to its right; and its children nodes are either valid BST nodes themselves or None / null.
Sample Usage
// Assume the following BST has already been created:
10
/ \
5 15
/ \ / \
2 5 13 22
/ \
1 14
// All operations below are performed sequentially.
insert(12): 10
/ \
5 15
/ \ / \
2 5 13 22
/ / \
1 12 14
remove(10): 12
/ \
5 15
/ \ / \
2 5 13 22
/ \
1 14
contains(15): true
Remove:
1. if the node has two children (convert two children case to one child case)
Then we get the min value node from right subtree
Then replace the remove node value with the min value
Then remove the min value node
--- Now we have handle the node has two children case, below all cases, node has at most one child ---2. If parent node does not exists, the remove node is the root node
Then replace the node with its left or right child (the replace order is important!)
AND If the remove node is the only node in tree
Then skip3. If there is parent node
Then link parnet node with remove node's left or right child
// Do not edit the class below except for
// the insert, contains, and remove methods.
// Feel free to add new properties and methods
// to the class.
class BST {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
insert(value) {
let current = this;
while(true) {
if (value >= current.value) {
if (current.right) {
current = current.right;
} else {
current.right = new BST(value);
break;
}
} else {
if (current.left) {
current = current.left;
} else {
current.left = new BST(value);
break;
}
}
}
return this;
}
contains(value) {
let current = this;
while(current) {
if (value > current.value) {
current = current.right;
} else if (value < current.value){
current = current.left;
} else {
return true;
}
}
return false;
}
remove(value, parentNode = null) {
let current = this;
while (current) {
if (value > current.value) {
parentNode = current;
current = current.right;
} else if (value < current.value) {
parentNode = current;
current = current.left;
} else {
// if the node has two children
if (current.left !== null && current.right !== null) {
const minNode = current.right.getMinNode();
current.value = minNode.value;
current.right.remove(minNode.value, current)
} else if (parentNode === null) {
// parentNode is the root node
if (current.left !==null) {
current.value = current.left.value;
current.right = current.left.right;
current.left = current.left.left;
} else if (current.right !==null) {
current.value = current.right.value;
current.left = current.right.left;
current.right = current.right.right;
} else {
// root node is the only node
}
} else if (parentNode.left == current) {
// parnet must has only one child
parentNode.left = current.left || current.right
} else if (parentNode.right == current) {
parentNode.right = current.left || current.right
}
break;
}
}
return this;
}
getMinNode() {
let current = this;
while (current.left) {
current = current.left;
}
return current;
}
}
// Do not edit the line below.
exports.BST = BST;