Skip to main content

Binary Trees

A binary tree is a hierarchical data structure where each node has at most two children, referred to as the left child and right child. A Binary Search Tree (BST) is a special type of binary tree where the left subtree of a node contains only nodes with values less than the node's value, and the right subtree contains only nodes with values greater than the node's value.

Implementation

class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right

class BinarySearchTree:
def __init__(self):
self.root = None

def insert(self, val):
if not self.root:
self.root = TreeNode(val)
return
curr = self.root
while curr:
if val < curr.val:
if not curr.left:
curr.left = TreeNode(val)
return
curr = curr.left
else:
if not curr.right:
curr.right = TreeNode(val)
return
curr = curr.right

Operations and Time Complexity

OperationDescriptionTime Complexity (BST Average)Time Complexity (BST Worst)
SearchFinding a specific valueO(logn)O(\log n)O(n)O(n)
InsertionAdding a new nodeO(logn)O(\log n)O(n)O(n)
DeletionRemoving a nodeO(logn)O(\log n)O(n)O(n)
Access Min/MaxFinding minimum/maximum valueO(logn)O(\log n)O(n)O(n)
Traversal (DFS)Depth-first traversal (pre/in/post-order)O(n)O(n)O(n)O(n)
Traversal (BFS)Breadth-first traversalO(n)O(n)O(n)O(n)
HeightFinding the height of the treeO(n)O(n)O(n)O(n)

Space Complexity

  • O(n)O(n) for storing n nodes
  • O(h)O(\text{h}) for recursive operations where h is the height of the tree
    • Best/Average case (balanced tree): O(logn)O(\log n)
    • Worst case (skewed tree): O(n)O(n)

Common Traversal Methods

Depth-First Search (DFS)

def dfs(node):
if not node:
return
# Process node (Pre-order)
dfs(node.left)
# Process node (In-order)
dfs(node.right)
# Process node (Post-order)

Breadth-First Search (BFS)

from collections import deque

def bfs(root):
if not root:
return
queue = deque([root])
while queue:
node = queue.popleft()
# Process node
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)

Use Cases

Binary trees, particularly BSTs, are useful for:

  • Implementing hierarchical data structures
  • Efficient searching and sorting
  • Priority queues (with heap implementation)
  • Expression parsing and evaluation
  • File system organization
  • Database indexing