Binary Search Tree (BST)
""" BINARY SEARCH TREE (BST)
----------------------------
Tree:
- A tree is a data structure where each node can connect to other nodes
- It is similar to how a family tree branches
BST Tree:
- A binary tree is a tree where each node has up to TWO children.
Analogy:
- Imagine a library shelf sorted alphabetically.
- All books that start with letters BEFORE "M" go to the left.
- All books that start with letters AFTER "M" go to the right.
This ordering helps searching very fast O(1).
Example: Sorting ages
---------------------
50
/ \
25 75
LEFT: 25 is younger (goes left)
RIGHT: 75 is older (goes right)
-------------------------------
"""
class Tree:
# A node in the binary tree (optional left/right child nodes)
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
node1 = Tree(25)
node2 = Tree(75)
root = Tree(50, node1, node2)
# Checking the BST
assert root.value > root.left.value # Left is smaller
assert root.value < root.right.value # Right is larger
print("Tree ok")
BST Search Node
""" BST SEARCH
--------------
Recursion:
- Tree have levels inside levels
- Recursion lets a function call itself
- It goes down the correct branch until it finds a match
How BST search works:
- If target == node.value -> found it (base case)
- If target < node.value -> go LEFT (smaller values)
- If target > node.value -> go RIGHT (larger values)
Edge cases:
- If we reach a None node, the value is not in the tree
- If empty tree return None immediately
Build a sample BST:
-------------------------------
50
/ \
25 75
/ \ / \
10 33 56 89
/ \ / \ / \ / \
4 11 30 40 52 61 82 95
-------------------------------
"""
class Tree:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def search(value, node):
# Base case: tree or branch ended without a match
if node is None:
return None
# Base case: found the value at the current node
if value == node.value:
return node
# Recursive cases: pick a side (left, right)
if value < node.value:
return search(value, node.left)
if value > node.value:
return search(value, node.right)
# Level 2
node7 = Tree(89, Tree(82), Tree(95))
node6 = Tree(56, Tree(52), Tree(61))
node5 = Tree(33, Tree(30), Tree(40))
node4 = Tree(10, Tree(4), Tree(11))
# Level 1
node3 = Tree(75, node6, node7)
node2 = Tree(25, node4, node5)
# Level 0 (root)
node1 = Tree(50, node2, node3)
# Example searches
node = search(61, node1)
print(node.value if node else None) # 61
node = search(13, node1) # 13 is not in the tree
print(node) # None