#! /usr/bin/python3
# ==================================================================
# Based on: www.youtube.com/watch?v=f5dU3xcE6ms
# Python Data Structure #5, binary Search Tree (BST)
#
# Note: this code uses private helper functions
# ==================================================================
import numpy as np
from random import randint
class node:
"""binary search tree node"""
def __init__(self,value=None):
self.value = value
self.left_child = None
self.right_child = None
class binary_search_tree:
"""binary search tree"""
def __init__(self):
self.root = None
def insert(self,value):
"""insert nodes into tree"""
if self.root == None:
self.root = node(value)
print("insert {} (root node)".format(value))
else:
self._insert(value,self.root)
def _insert(self,value,cur_node):
"""insert nodes into tree - helper function"""
if value < cur_node.value:
if cur_node.left_child == None:
cur_node.left_child = node(value)
print("insert {}".format(value))
else:
self._insert(value,cur_node.left_child)
elif value > cur_node.value:
if cur_node.right_child == None:
cur_node.right_child = node(value)
print("insert {}".format(value))
else:
self._insert(value,cur_node.right_child)
else:
print("value {} is already in tree".format(value))
def print_tree(self):
"""print tree in order one line per node"""
if self.root != None:
self._print_tree(self.root)
else:
print("Tree empty")
def _print_tree(self,cur_node):
"""print tree in order one line per node - helper function"""
if cur_node != None:
self._print_tree(cur_node.left_child)
print(str(cur_node.value))
self._print_tree(cur_node.right_child)
def print_tree_structure(self):
"""print tree structor in order"""
if self.root != None:
self._print_tree_structure(self.root,1)
else:
print("Tree empty")
def _print_tree_structure(self,cur_node,n):
"""print tree structure in order - helper function"""
if cur_node != None:
self._print_tree_structure(cur_node.right_child,n+1)
print("---"*n + " " + str(cur_node.value))
self._print_tree_structure(cur_node.left_child,n+1)
def height(self):
"""find maxmum tree height"""
if self.root != None:
return self._height(self.root,0)
else:
return 0
def _height(self,cur_node,cur_height):
"""find maximum tree height - helper function"""
if cur_node == None: return cur_height
left_height = self._height(cur_node.left_child,cur_height+1)
right_height = self._height(cur_node.right_child,cur_height+1)
return max(left_height,right_height)
# ---- main --------------------------------------------------------
def large_tree(tree,num_elms=100,max_int=1000):
"""create a large test tree"""
for _ in range(num_elms):
cur_elem = randint(0,max_int)
tree.insert(cur_elem)
return tree
def small_tree(tree):
"""create a small test tree"""
values = [5,2,7,9,6,3,10,4,1,2]
print(values)
for v in values:
tree.insert(int(v))
return tree
def worst_case_tree(tree):
"""create a small worst case test tree"""
values = [10,9,7,5,4,3,2,1,11,12,13,14,15,16,17]
print(values)
print("------------------------------------------------------")
for v in values:
tree.insert(int(v))
return tree
##tree = binary_search_tree()
##tree = large_tree(tree)
##tree.print_tree()
##tree = binary_search_tree()
##tree = small_tree(tree)
##tree.print_tree_structure()
tree = binary_search_tree()
print("------------------------------------------------------")
tree = worst_case_tree(tree)
print("------------------------------------------------------")
tree.print_tree_structure()
print("------------------------------------------------------")
print("Tree height is {}".format(str(tree.height())))