-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathbinary_search_trees.py
More file actions
199 lines (176 loc) · 4.59 KB
/
binary_search_trees.py
File metadata and controls
199 lines (176 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
This file contains Python implementations of binary search tree
from Intro to Algorithms (Cormen et al.).
The aim here is not efficient Python implementations
but to duplicate the pseudo-code in the book as closely as possible.
Also, since the goal is to help students to see how the algorithm
works, there are print statements placed at key points in the code.
The performance of each function is stated in the docstring, and
loop invariants are expressed as assert statements when they
are not too complex.
This file contains:
The class definition for Node.
The class definition for Tree.
tree_insert()
inorder_tree_walk()
tree_search()
iter_tree_search()
tree_minimum()
tree_maximum()
tree_successor()
Plus auxilliary functions that support the above.
"""
class Tree():
"""
The binary search tree.
"""
def __init__(self, root=None):
self.root = root
def __str__(self):
return "Binary tree with root of " + str(self.root)
class Node():
"""
The nodes in our binary search tree.
"""
def __init__(self, k):
"""
Args:
k: this node's key
Returns:
None
"""
self.key = k
self.p = None
self.left = None
self.right = None
def __str__(self):
return str(self.key)
def tree_insert(t, z):
"""
Insert a node in a bst.
Args:
t: the tree in which to insert
z: the node to insert
Return:
None
"""
y = None
x = t.root
while x is not None:
print("Looping: x is " + str(x.key) + "; z is " + str(z.key))
y = x
if z.key < x.key:
x = x.left
else:
x = x.right
z.p = y
if y is None:
t.root = z # the tree was empty
elif z.key < y.key:
y.left = z
else:
y.right = z
return z
def inorder_tree_walk(x, l=None):
"""
Walk and print the tree in order.
Args:
x: the node at which to start the walk
Returns:
None
"""
if l is None:
l = []
if x is not None:
inorder_tree_walk(x.left, l)
l.append(x)
print(str(x.key))
inorder_tree_walk(x.right, l)
return l
def tree_search(x, k):
"""
Recursively searches a binary tree for a particular key.
Args:
x: the node at which to start the search
Returns:
None, or the node containing the key.
"""
if x is None:
return None
elif k == x.key:
return x
elif k < x.key:
return tree_search(x.left, k)
else:
return tree_search(x.right, k)
def iter_tree_search(x, k):
"""
Iteratively searches a binary tree for a particular key.
Args:
x: the node at which to start the search
Returns:
None, or the node containing the key.
"""
while x is not None and k != x.key:
if k < x.key:
x = x.left
else:
x = x.right
return x
def tree_minimum(x):
"""
Searches a tree for the node with the min key.
Args:
x: the node at which to start the search
Returns:
The node with the min key in the tree, or
None if the tree is empty.
"""
if x is None:
return None
while x.left is not None:
x = x.left
print("min is " + str(x.key))
return x
def tree_maximum(x):
"""
Searches a tree for the node with the max key.
Args:
x: the node at which to start the search
Returns:
The node with the max key in the tree, or
None if the tree is empty.
"""
if x is None:
return None
while x.right is not None:
x = x.right
print("max is " + str(x.key))
return x
def tree_successor(x):
"""
Searches a tree for the node with the smallest key
greater than x.key.
Args:
x: the node at which to start the search
Returns:
The node with the successor key, or
None if x has the largest key.
"""
if x is None:
return None
elif x.right is not None:
return tree_minimum(x.right)
else:
orig_x = x
y = x.p
if y is not None:
print("Climbing tree to check " + str(y.key))
while y is not None and x == y.right:
x = y
y = y.p
print("successor of x (" + str(x.key)
+ ") is " + str(y.key))
return y