class Node { constructor(value) { this.value = value; this.left = null; this.right = null; } } class BST { constructor() { this.root = null; } insert(value) { const newNode = new Node(value); if (!this.root) { this.root = newNode; return; } let current = this.root; while (true) { if (value < current.value) { if (!current.left) { current.left = newNode; return; } current = current.left; } else { if (!current.right) { current.right = newNode; return; } current = current.right; } } } inOrder(node, result = []) { if (!node) return result; this.inOrder(node.left, result); result.push(node.value); this.inOrder(node.right, result); return result; } } const bst = new BST(); bst.insert(10); bst.insert(5); bst.insert(15); bst.insert(3); bst.insert(7); console.log(bst.inOrder(bst.root).join(' -> ') + ' -> null');
In-order traversal visits nodes in ascending order for a BST. After inserting 10, 5, 15, 3, 7, the sorted order is 3, 5, 7, 10, 15.
The BST property lets us decide to go left or right based on comparison, effectively halving the search space each time, leading to O(log n) average search time.
class Node { constructor(value) { this.value = value; this.left = null; this.right = null; } } class BST { constructor() { this.root = null; } insert(value) { const newNode = new Node(value); if (!this.root) { this.root = newNode; return; } let current = this.root; while (true) { if (value <= current.value) { if (!current.left) { current.left = newNode; return; } current = current.left; } else { if (!current.right) { current.right = newNode; return; } current = current.right; } } } } const bst = new BST(); bst.insert(10); bst.insert(10); console.log(bst.root.left.value);
The code inserts duplicates to the left subtree by using <= comparison, so inserting 10 twice places the second 10 as the left child.
class Node { constructor(value) { this.value = value; this.left = null; this.right = null; } } class BST { constructor() { this.root = null; } insert(value) { const newNode = new Node(value); if (!this.root) { this.root = newNode; return; } let current = this.root; while (true) { if (value < current.value) { if (!current.left) { current.left = newNode; return; } current = current.left; } else { if (!current.right) { current.right = newNode; return; } current = current.right; } } } findMin(node) { while (node.left) { node = node.left; } return node; } delete(value, node = this.root) { if (!node) return null; if (value < node.value) { node.left = this.delete(value, node.left); } else if (value > node.value) { node.right = this.delete(value, node.right); } else { if (!node.left) return node.right; if (!node.right) return node.left; let minRight = this.findMin(node.right); node.value = minRight.value; node.right = this.delete(minRight.value, node.right); } return node; } inOrder(node, result = []) { if (!node) return result; this.inOrder(node.left, result); result.push(node.value); this.inOrder(node.right, result); return result; } } const bst = new BST(); bst.insert(10); bst.insert(5); bst.insert(15); bst.insert(3); bst.insert(7); bst.delete(5); console.log(bst.inOrder(bst.root).join(' -> ') + ' -> null');
Deleting 5 replaces it with 7 (smallest in right subtree). The in-order traversal then is 3, 7, 10, 15.
Without the BST property, the tree is just a binary tree with no order, so search may need to visit all nodes, leading to O(n) time.
