Skip to main content

Binary Search Tree

SpaceTime
AccessLookupInsertionDeletion
O(n)O(log n)O(log n)O(log n)O(log n)

Definition​

Binary Search Tree is a data structure that organizes elements in a sorted manner, where each node can have at most 2 children: a left and a right child. This makes it efficient for searching, insertion, and deletion operations.

Simplified

Binary Search Tree is like a library system. Each book (or "node") has a unique identifier and up to 2 related books. You start from a certain point (the "root") and go left if the book you're looking for has a smaller identifier, right if it's larger. This way, you eliminate half of the remaining books with each step, making the search efficient.

Practice​

AspectPseudo Code
Insertion
insert(root, key):
if root == ø:
return new Node(key)
if key < root.key:
root.left = insert(root.left, key)
else if key > root.key:
root.right = insert(root.right, key)
return root
Search Node
search(root, key):
if root == ø or root.key == key:
return root
if key < root.key:
return search(root.left, key)
return search(root.right, key)
Find MIN
find_min(root):
while root.left != ø:
root = root.left
return root
Find MAX
find_max(root):
while root.right != ø:
root = root.right
return root
Find Successor
find_successor(root, key):
if root == ø:
return ø

successor = ø
while root != ø:
if key < root.key:
successor = root
root = root.left
else:
root = root.right

return successor
Find Predecessor
find_predecessor(root, key):
if root == ø:
return ø

predecessor = ø
while root != ø:
if key > root.key:
predecessor = root
root = root.right
else:
root = root.left

return predecessor
Deletion
delete_node(root, key):
if root ø:
return ø

// Locate the node to be deleted
if key < root.key:
root.left = delete_node(root.left, key)
else if key > root.key:
root.right = delete_node(root.right, key)
else:
// Node with the key is found
// Case 1: Node with only one child or no child
if root.left == ø:
return root.right
else if root.right == ø:
return root.left

// Case 2: Node with two children
// Find the inorder successor (smallest node in the right subtree)
successor = root.right
// Find MIN: Find the leftmost leaf in the right subtree
while successor.left != ø:
successor = successor.left
root.key = successor.key

// Delete the inorder successor
root.right = delete_node(root.right, successor.key)

return root
BFS Recursive
bfs_recursive(root):
if root == ø:
return

queue = Queue()
queue.enqueue(root)

bfs_helper(queue)

bfs_helper(queue):
if queue == ø:
return

current = queue.dequeue()
process(current)

if current.left != ø:
queue.enqueue(current.left)
if current.right != ø:
queue.enqueue(current.right)

bfs_helper(queue)
BFS Iterative
bfs_iterative(root):
if root == ø:
return

queue = Queue()
queue.enqueue(root)

while queue != ø:
current = queue.dequeue()
process(current)

if current.left != ø:
queue.enqueue(current.left)
if current.right != ø:
queue.enqueue(current.right)
DFS PreOrder Recursive
dfs_pre_order_recursive(root):
if root == ø:
return
print root.value
dfs_pre_order_recursive(root.left)
dfs_pre_order_recursive(root.right)
DFS PreOrder Iterative
dfs_preorder_iterative(root):
if root == ø:
return

stack = Stack()
stack.push(root)

while stack != ø:
current = stack.pop()
process(current)

if current.right != ø:
stack.push(current.right)
if current.left != ø:
stack.push(current.left)
DFS InOrder Recursive
dfs_in_order_recursive(root):
if root == ø:
return
dfs_in_order_recursive(root.left)
print root.value
dfs_in_order_recursive(root.right)
DFS InOrder Iterative
dfs_inorder_iterative(root):
if root == ø:
return

stack = Stack()
current = root

while current != ø or stack != ø:
while current != ø:
stack.push(current)
current = current.left

current = stack.pop()
process(current)
current = current.right
DFS PostOrder Recursive
dfs_post_order_recursive(root):
if root == ø:
return
dfs_post_order_recursive(root.left)
dfs_post_order_recursive(root.right)
print root.value
DFS PostOrder Iterative
dfs_postorder_iterative(root):
if root == ø:
return

stack1 = Stack()
stack2 = Stack()
stack1.push(root)

while stack1 != ø:
current = stack1.pop()
stack2.push(current)

if current.left != ø:
stack1.push(current.left)
if current.right != ø:
stack1.push(current.right)

while stack2 != ø:
process(stack2.pop())