Skip to content

Commit ff1d55d

Browse files
committed
Rewrote the previous BST implementation (only have and )
1 parent 8cb1c4f commit ff1d55d

File tree

2 files changed

+138
-190
lines changed

2 files changed

+138
-190
lines changed

chap06_trees/binary_search_tree.py

Lines changed: 0 additions & 190 deletions
This file was deleted.

chap06_trees/tree_binarysearchtree.py

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import sys
2+
3+
if len(sys.argv) == 2:
4+
if sys.argv[1] == 'debug':
5+
DEBUG = True
6+
else:
7+
DEBUG = False
8+
else:
9+
DEBUG = False
10+
11+
12+
class BinarySearchTree:
13+
14+
class __Node:
15+
def __init__(self, value, left=None, right=None):
16+
self.value = value
17+
self.left = left
18+
self.right = right
19+
20+
def get_value(self):
21+
return self.value
22+
23+
def get_left(self):
24+
return self.left
25+
26+
def get_right(self):
27+
return self.right
28+
29+
def set_value(self, new_value):
30+
self.value = new_value
31+
32+
def set_left(self, new_left):
33+
self.left = new_left
34+
35+
def set_right(self, new_right):
36+
self.right = new_right
37+
38+
def __iter__(self):
39+
"""
40+
In-order traversal (from the bottom)
41+
"""
42+
if self.left is not None:
43+
for elem in self.left:
44+
yield elem
45+
else:
46+
if DEBUG:
47+
yield f"\nI'm None here! #LEFT\t(at {str(self)[44:-2]})"
48+
49+
yield self.value
50+
51+
if self.right is not None:
52+
for elem in self.right:
53+
yield elem
54+
else:
55+
if DEBUG:
56+
yield f"I'm None here! #RIGHT\t(at {str(self)[44:-2]}) \n"
57+
58+
def __init__(self):
59+
self.root = None
60+
61+
def insert(self, value):
62+
"""
63+
O(logN) all the way (insert, delete, lookup)
64+
65+
It cannot guarantee the O(logN), keyword: more-space, balanced, sorted
66+
If the values are to inserted were already sorted, it
67+
- insert n items became O(N^2) in the worse case
68+
- the tree being built will become a "long stick" (~= linked list)
69+
"""
70+
71+
def __insert(root, value):
72+
73+
# relation with recursion
74+
# - outside: initialize the first element as the root node
75+
# - inside : tranform any received vals into a `__Node` object
76+
if root is None:
77+
return BinarySearchTree.__Node(value)
78+
79+
# fmt: off
80+
# relation with recursion
81+
# - outside: compare between `root` and inserted (level 1 and 2)
82+
# - inside : replace with the subtree's root (via `get_left/right`)
83+
if value < root.get_value():
84+
85+
# get the `__Node` instance for L/R via the recursion inside
86+
root.set_left(
87+
__insert(
88+
# enter the subtrees via replacing the `root` in recur
89+
root.get_left(), value
90+
)
91+
)
92+
93+
else:
94+
95+
# get the `__Node` instance for L/R via the recursion inside
96+
root.set_right(
97+
__insert(
98+
# enter the subtrees via replacing the `root` in recur
99+
root.get_right(), value
100+
)
101+
)
102+
103+
return root
104+
105+
# call nested function
106+
self.root = __insert(self.root, value)
107+
108+
def __iter__(self):
109+
"""
110+
Nothing fancy here, all the fancy stuff are inside the `__Node` class
111+
"""
112+
113+
# call the `__iter__` inside the BST, or return `[]` if it's empty
114+
if self.root is not None:
115+
return self.root.__iter__()
116+
else:
117+
return [].__iter__()
118+
119+
120+
def main():
121+
tree = BinarySearchTree()
122+
lst = [5, 8, 2, 1, 4, 9, 6, 7]
123+
124+
for elem in lst:
125+
tree.insert(elem)
126+
127+
# see 'bst_inorder.log' if you wanna know how the `__iter__` works :)
128+
129+
if DEBUG is True:
130+
for elem in tree:
131+
print(elem)
132+
else:
133+
assert [elem for elem in tree] == [1, 2, 4, 5, 6, 7, 8, 9]
134+
print("Assertion passed.")
135+
136+
137+
if "__main__" == __name__:
138+
main()

0 commit comments

Comments
 (0)