-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbst.py
131 lines (122 loc) · 4.43 KB
/
bst.py
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
class BST(object):
"""
Simple binary search tree implementation.
This BST supports insert, find, and delete-min operations.
Each tree contains some (possibly 0) BSTnode objects, representing nodes,
and a pointer to the root.
"""
def __init__(self):
self.root = None
def insert(self, t):
"""Insert key t into this BST, modifying it in-place."""
new = BSTnode(t)
if self.root is None:
self.root = new
else:
node = self.root
while True:
if t < node.key:
# Go left
if node.left is None:
node.left = new
new.parent = node
break
node = node.left
else:
# Go right
if node.right is None:
node.right = new
new.parent = node
break
node = node.right
return new
def find(self, t):
"""Return the node for key t if is in the tree, or None otherwise."""
node = self.root
while node is not None:
if t == node.key:
return node
elif t < node.key:
node = node.left
else:
node = node.right
return None
def delete_min(self):
"""Delete the minimum key (and return the old node containing it)."""
if self.root is None:
return None, None
else:
# Walk to leftmost node.
node = self.root
while node.left is not None:
node = node.left
# Remove that node and promote its right subtree.
if node.parent is not None:
node.parent.left = node.right
else: # The root was smallest.
self.root = node.right
if node.right is not None:
node.right.parent = node.parent
parent = node.parent
node.disconnect()
return node, parent
def __str__(self):
if self.root is None: return '<empty tree>'
def recurse(node):
if node is None: return [], 0, 0
label = str(node.key)
left_lines, left_pos, left_width = recurse(node.left)
right_lines, right_pos, right_width = recurse(node.right)
middle = max(right_pos + left_width - left_pos + 1, len(label), 2)
pos = left_pos + middle // 2
width = left_pos + middle + right_width - right_pos
while len(left_lines) < len(right_lines):
left_lines.append(' ' * left_width)
while len(right_lines) < len(left_lines):
right_lines.append(' ' * right_width)
if (middle - len(label)) % 2 == 1 and node.parent is not None and \
node is node.parent.left and len(label) < middle:
label += '.'
label = label.center(middle, '.')
if label[0] == '.': label = ' ' + label[1:]
if label[-1] == '.': label = label[:-1] + ' '
lines = [' ' * left_pos + label + ' ' * (right_width - right_pos),
' ' * left_pos + '/' + ' ' * (middle-2) +
'\\' + ' ' * (right_width - right_pos)] + \
[left_line + ' ' * (width - left_width - right_width) +
right_line
for left_line, right_line in zip(left_lines, right_lines)]
return lines, pos, width
return '\n'.join(recurse(self.root) [0])
class BSTnode(object):
"""
Representation of a node in a binary search tree.
Has a left child, right child, and key value.
"""
def __init__(self, t):
"""Create a new leaf with key t."""
self.key = t
self.disconnect()
def disconnect(self):
self.left = None
self.right = None
self.parent = None
def test(args=None, BSTtype=BST):
import random, sys
if not args:
args = sys.argv[1:]
if not args:
print 'usage: %s <number-of-random-items | item item item ...>' % \
sys.argv[0]
sys.exit()
elif len(args) == 1:
items = (random.randrange(100) for i in xrange(int(args[0])))
else:
items = [int(i) for i in args]
tree = BSTtype()
print tree
for item in items:
tree.insert(item)
print
print tree
if __name__ == '__main__': test()