class Node {
constructor(val) {
this.val = val;
this.left = null;
this.right = null;
}
}
class BST {
constructor() {
this.root = null;
}
insert(val) {
const newNode = new Node(val);
if (!this.root) {
this.root = newNode;
return;
}
let curr = this.root;
while (true) {
if (val < curr.val) {
if (!curr.left) {
curr.left = newNode;
return;
}
curr = curr.left;
} else {
if (!curr.right) {
curr.right = newNode;
return;
}
curr = curr.right;
}
}
}
delete(val) {
this.root = this._deleteRec(this.root, val);
}
_deleteRec(node, val) {
if (!node) return null; // base case: node not found
if (val < node.val) {
node.left = this._deleteRec(node.left, val); // go left
} else if (val > node.val) {
node.right = this._deleteRec(node.right, val); // go right
} else {
// node found
if (!node.left && !node.right) {
return null; // no children, remove node
} else if (!node.left) {
return node.right; // only right child, replace node
} else if (!node.right) {
return node.left; // only left child, replace node
} else {
// two children: find inorder successor
let succ = this._minValueNode(node.right);
node.val = succ.val; // replace value
node.right = this._deleteRec(node.right, succ.val); // delete successor
}
}
return node;
}
_minValueNode(node) {
let current = node;
while (current.left) {
current = current.left; // go left to find min
}
return current;
}
inorder() {
const res = [];
function traverse(node) {
if (!node) return;
traverse(node.left);
res.push(node.val);
traverse(node.right);
}
traverse(this.root);
return res.join(' -> ') + ' -> null';
}
}
// Driver code
const bst = new BST();
[5,3,7,2,4,8].forEach(v => bst.insert(v));
bst.delete(3);
console.log(bst.inorder());if (!node) return null; // base case: node not found
stop recursion when node is null
if (val < node.val) {
node.left = this._deleteRec(node.left, val); // go left
}
search left subtree for node to delete
else if (val > node.val) {
node.right = this._deleteRec(node.right, val); // go right
}
search right subtree for node to delete
if (!node.left && !node.right) {
return null; // no children, remove node
}
delete leaf node by returning null
else if (!node.left) {
return node.right; // only right child, replace node
}
replace node with right child if no left child
else if (!node.right) {
return node.left; // only left child, replace node
}
replace node with left child if no right child
let succ = this._minValueNode(node.right);
node.val = succ.val;
node.right = this._deleteRec(node.right, succ.val);
replace node value with inorder successor and delete successor
while (current.left) {
current = current.left; // go left to find min
}
find minimum value node in right subtree
2 -> 4 -> 5 -> 7 -> 8 -> null