"""Binary Search Tree
Included:
- Insert
- Find data/ minimum/ maximum
- Size
- Height
- Traversals (Inorder, preorder, postorder)
- Test Code for it
Not included:
- Delete
- Display (as 2D BST)
and others...
"""
class Node:
def __init__(self, data, start=None):
self.data = data
self.left = self.right = start
class BinarySearchTree:
def __init__(self):
self.root = None
def put(self, data):
if self.root is None:
self.root = Node(data)
else:
curr = self.root
while curr:
if data < curr.data:
if curr.left:
curr = curr.left
else:
curr.left = Node(data)
break
else:
if curr.right:
curr = curr.right
else:
curr.right = Node(data)
break
def find(self, data):
curr = self.root
while curr:
if data < curr.data:
curr = curr.left
elif data > curr.data:
curr = curr.right
else:
return True
return False
def min_of(self):
curr = self.root
while curr.left:
curr = curr.left
return curr.data
def max_of(self):
curr = self.root
while curr.right:
curr = curr.right
return curr.data
def size(self):
def go(node):
if node:
return 1 + go(node.left) + go(node.right)
return 0
return go(self.root)
def height(self):
def go(node):
if node:
return 1 + max(go(node.left), go(node.right))
return -1
return go(self.root)
def in_order(self):
lst = []
def go(node):
nonlocal lst
if node:
go(node.left)
lst.append(node.data)
go(node.right)
go(self.root)
return lst
def pre_order(self):
lst = []
def go(node):
nonlocal lst
if node:
lst.append(node.data)
go(node.left)
go(node.right)
go(self.root)
return lst
def post_order(self):
lst = []
def go(node):
nonlocal lst
if node:
go(node.left)
go(node.right)
lst.append(node.data)
go(self.root)
return lst
from random import randint, sample
def BST_tester(BST):
r = randint(5, 10)
lst = [randint(10, 100) for _ in range(r)]
print(f"List: {lst}",
f"Sorted: {sorted(lst)}",
sep = "
", end = "
")
B = BST()
for item in lst:
B.put(item)
lst.sort()
print("AFTER INSERTION:",
f"Size: {B.size()} | {B.size() == len(lst)}",
f"Height: {B.height()} | I can't code the display for this",
f"Min: {B.min_()} | {B.min_() == min(lst)}",
f"Max: {B.max_()} | {B.max_() == max(lst)}",
sep = "
", end = "
")
items = sample(lst, 5) + [randint(10, 100) for _ in range(5)]
found = [B.find(_) for _ in items]
zipped = list(zip(items, found))
inlst, notinlst = zipped[:5], zipped[5:]
print(f"Sampled from lst: {inlst} | All True: {all(found[:5])}",
f"Random: {notinlst}",
sep = "
", end = "
")
print(f"Inord: {B.in_ord()} | Correct Insertion: {lst == B.in_ord()}",
f"Preord: {B.pre_ord()}",
f"Postord: {B.post_ord()}",
sep = "
")
BST_tester(BST)