Skip to content

Commit f33b5ac

Browse files
committed
committed from zkp
1 parent 59006ad commit f33b5ac

1 file changed

Lines changed: 182 additions & 0 deletions

File tree

  • Introduction to algorithms

Introduction to algorithms/BST.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
BST_node_date = [
2+
{'key': 60, 'left': 12, 'right': 90, 'is_root': True},
3+
{'key': 12, 'left': 4, 'right': 41, 'is_root': False},
4+
{'key': 90, 'left': 71, 'right': 100, 'is_root': False},
5+
{'key': 4, 'left': 1, 'right': None, 'is_root': False},
6+
{'key': 41, 'left': 29, 'right': None, 'is_root': False},
7+
{'key': 71, 'left': None, 'right': 84, 'is_root': False},
8+
{'key': 100, 'left': None, 'right': None, 'is_root': False},
9+
{'key': 1, 'left': None, 'right': None, 'is_root': False},
10+
{'key': 29, 'left': 23, 'right': 37, 'is_root': False},
11+
{'key': 84, 'left': None, 'right': None, 'is_root': False},
12+
{'key': 23, 'left': None, 'right': None, 'is_root': False},
13+
{'key': 37, 'left': None, 'right': None, 'is_root': False}
14+
]
15+
16+
17+
class BST_node(object):
18+
def __init__(self, key, value, left=None, right=None):
19+
self.key, self.value, self.left, self.right = key, value, left, right
20+
21+
22+
class BST(object):
23+
def __init__(self, root=None):
24+
self.root = root
25+
26+
@classmethod
27+
def build_from(cls, BST_node_date):
28+
cls.size = 0
29+
node_dict = {}
30+
for node_data in BST_node_date:
31+
key = node_data['key']
32+
node_dict[key] = BST_node(key, value=key)
33+
34+
for node_data in BST_node_date:
35+
key = node_data['key']
36+
node = node_dict[key]
37+
if node_data['is_root']:
38+
root = node
39+
node.left = node_dict.get(node_data['left'])
40+
node.right = node_dict.get(node_data['right'])
41+
cls.size += 1
42+
return cls(root)
43+
44+
def _bst_search(self, subtree, key):
45+
if subtree is None:
46+
return None
47+
elif subtree.key > key:
48+
return self._bst_search(subtree.left, key)
49+
elif subtree.key < key:
50+
return self._bst_search(subtree.right, key)
51+
else:
52+
return subtree
53+
54+
def __contains__(self, key):
55+
return self._bst_search(self.root, key) is not None
56+
57+
def get(self, key, default=None):
58+
node = self._bst_search(self.root, key)
59+
if node is None:
60+
return default
61+
else:
62+
return node.value
63+
64+
def _bst_min_node(self, subtree):
65+
if subtree is None:
66+
return None
67+
elif subtree.left is None:
68+
return subtree
69+
else:
70+
return self._bst_min_node(subtree.left)
71+
72+
def bst_min(self):
73+
node = self._bst_min_node(self.root)
74+
return node.value if node else None
75+
76+
def _bst_max_node(self, subtree):
77+
if subtree is None:
78+
return None
79+
elif subtree.right is None:
80+
return subtree
81+
else:
82+
return self._bst_max_node(subtree.right)
83+
84+
def bst_max(self):
85+
node = self._bst_max_node(self.root)
86+
return node.value if node else None
87+
88+
def _bst_insert(self, subtree, key, value):
89+
if subtree is None:
90+
subtree = BST_node(key, value)
91+
elif subtree.key > key:
92+
subtree.left = self._bst_insert(subtree.left, key, value)
93+
elif subtree.key < key:
94+
subtree.right = self._bst_insert(subtree.right, key, value)
95+
return subtree
96+
97+
def add(self, key, value):
98+
node = self._bst_search(self.root, key)
99+
if node is not None:
100+
node.value = value
101+
return False
102+
else:
103+
self.root = self._bst_insert(self.root, key, value)
104+
self.size += 1
105+
return True
106+
107+
def _bst_remove(self, subtree, key):
108+
if subtree is None:
109+
return None
110+
elif subtree.key < key:
111+
subtree.right = self._bst_remove(subtree.right, key)
112+
return subtree
113+
elif subtree.key > key:
114+
subtree.left = self._bst_remove(subtree.left, key)
115+
return subtree
116+
else:
117+
if subtree.left is None and subtree.right is None:
118+
return None
119+
elif subtree.left is None or subtree.right is None:
120+
if subtree.left is not None:
121+
return subtree.left
122+
else:
123+
return subtree.right
124+
else:
125+
successor_node = self._bst_min_node(subtree.right)
126+
subtree.key, subtree.value = successor_node.key, successor_node.value
127+
subtree.right = self._bst_remove(subtree.right, successor_node.key)
128+
return subtree
129+
130+
def remove(self, key):
131+
assert key in self
132+
self.size -= 1
133+
return self._bst_remove(self.root, key)
134+
135+
def preorder_traversal(self, subtree):
136+
if subtree is not None:
137+
self.preorder_traversal(subtree.left)
138+
print(subtree.key, subtree.value)
139+
self.preorder_traversal(subtree.right)
140+
141+
def reverse(self, subtree):
142+
if subtree is not None:
143+
subtree.left, subtree.right = subtree.right, subtree.left
144+
self.reverse(subtree.left)
145+
self.reverse(subtree.right)
146+
147+
148+
# bst = BST.build_from(BST_node_date)
149+
# bst.add(120, 120)
150+
# bst.add(0, 0)
151+
# bst.add(3,3)
152+
# bst.preorder_traversal(bst.root)
153+
# bst.remove(3)
154+
# bst.remove(90)
155+
# bst.remove(60)
156+
# bst.remove(0)
157+
# bst.preorder_traversal(bst.root)
158+
def test_bst_tree():
159+
bst = BST.build_from(BST_node_date)
160+
for node_dict in BST_node_date:
161+
key = node_dict['key']
162+
assert bst.get(key) == key
163+
assert bst.size == len(BST_node_date)
164+
assert bst.get(-1) is None # 单例的 None 我们用 is 来比较
165+
166+
assert bst.bst_min() == 1
167+
168+
bst.add(0, 0)
169+
assert bst.bst_min() == 0
170+
171+
bst.remove(12)
172+
assert bst.get(12) is None
173+
174+
bst.remove(1)
175+
assert bst.get(1) is None
176+
177+
bst.remove(29)
178+
assert bst.get(29) is None
179+
180+
181+
if __name__ == "__main__":
182+
test_bst_tree()

0 commit comments

Comments
 (0)