Implement a BinarySearchTree class — a specialization of a binary tree that maintains an ordering invariant at every node: everything in the left subtree is smaller than the node, and everything in the right subtree is larger. That single rule turns lookup into binary search: at each node you compare, descend left or right, and discard the other half of the tree. Insert and delete must preserve the invariant, and delete is the operation that earns the hard tier — three structural cases, one of which (the two-child case) needs the in-order successor trick.
class BinarySearchTree {
insert(value: number): void;
search(value: number): boolean;
delete(value: number): void;
inorder(): number[]; // helper — returns values in sorted ascending order
}
const t = new BinarySearchTree();
[5, 3, 8, 1, 4, 7, 9].forEach((v) => t.insert(v));
t.search(4); // true
t.search(6); // false (close, but not present — no "nearest" semantics)
t.inorder(); // [1, 3, 4, 5, 7, 8, 9] — sorted, because that's what BST inorder gives you
// Delete a leaf — simplest case
t.delete(1);
t.inorder(); // [3, 4, 5, 7, 8, 9]
// Delete a node with one child — child takes the parent's slot
t.delete(9); // 9 was a leaf already; deleting 8 next would have one child (7)
t.delete(8);
t.inorder(); // [3, 4, 5, 7]
// Delete a node with two children — replaced by its in-order successor
const u = new BinarySearchTree();
[5, 3, 8, 1, 4, 7, 9].forEach((v) => u.insert(v));
u.delete(3); // 3 has children 1 and 4; successor is 4; 3's slot now holds 4
u.inorder(); // [1, 4, 5, 7, 8, 9]
insert and delete.insert(5); insert(5) produces two 5 nodes, the second as the right descendant of the first). Other valid choices: reject duplicates, or store a count per node. Pick one and stay consistent.delete has three cases — leaf (unhook), one child (child replaces the node), two children (copy the in-order successor's value into the slot, then recursively delete the successor from the right subtree).delete on missing values is a no-op — no throw, no error; the tree is unchanged.O(log n) for a balanced tree, O(n) for a degenerate (chain-shaped) tree. This implementation does not self-balance; insert/search/delete are worst-case O(n). Self-balancing variants (AVL, red-black) are out of scope here.< and > operators behave predictably on numbers; on mixed or non-number values they coerce and the invariant becomes meaningless.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.