class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}
function deleteNode(root: TreeNode | null, key: number): TreeNode | null {
if (root === null) return null; // base case: empty tree
if (key < root.val) {
root.left = deleteNode(root.left, key); // search left subtree
} else if (key > root.val) {
root.right = deleteNode(root.right, key); // search right subtree
} else {
// found node to delete
if (root.left === null) {
return root.right; // replace node with right child
} else if (root.right === null) {
return root.left; // replace node with left child
} else {
// node with two children: find inorder successor
let successor = root.right;
while (successor.left !== null) {
successor = successor.left; // find smallest in right subtree
}
root.val = successor.val; // copy successor value
root.right = deleteNode(root.right, successor.val); // delete successor
}
}
return root;
}
function printBST(root: TreeNode | null): string {
if (root === null) return "null";
const leftStr = printBST(root.left);
const rightStr = printBST(root.right);
return `${root.val} -> (${leftStr}, ${rightStr})`;
}
// Driver code
const root = new TreeNode(5,
new TreeNode(3,
new TreeNode(2),
new TreeNode(4)
),
new TreeNode(7,
null,
new TreeNode(8)
)
);
const newRoot = deleteNode(root, 3);
console.log(printBST(newRoot));if (root === null) return null;
stop recursion if tree/subtree is empty
if (key < root.val) { root.left = deleteNode(root.left, key); }
search left subtree if key smaller
else if (key > root.val) { root.right = deleteNode(root.right, key); }
search right subtree if key larger
else { // found node to delete
handle deletion cases
if (root.left === null) { return root.right; }
replace node with right child if no left child
else if (root.right === null) { return root.left; }
replace node with left child if no right child
else { let successor = root.right; while (successor.left !== null) { successor = successor.left; } root.val = successor.val; root.right = deleteNode(root.right, successor.val); }
replace node with inorder successor and delete successor
return updated subtree root
5 -> (4 -> (2 -> (null, null), null), 7 -> (null, 8 -> (null, null)))