1+ # 构建二叉查找树(非平衡)
2+ class TreeNode :
3+ def __init__ (self , key , val , left = None , right = None , parent = None ):
4+ self .key = key
5+ self .payload = val
6+ self .leftChild = left
7+ self .rightChild = right
8+ self .parent = parent
9+
10+ def hasLeftChild (self ):
11+ return self .leftChild
12+
13+ def hasRightChild (self ):
14+ return self .rightChild
15+
16+ def isLeftChild (self ):
17+ return self .parent and self .parent .leftChild == self
18+
19+ def isRightChild (self ):
20+ return self .parent and self .parent .rightChild == self
21+
22+ def isRoot (self ):
23+ return not self .parent
24+
25+ def isLeaf (self ):
26+ return not (self .rightChild or self .leftChild )
27+
28+ def hasAnyChildren (self ):
29+ return self .rightChild or self .leftChild
30+
31+ def hasBothChildren (self ):
32+ return self .rightChild and self .leftChild
33+
34+ def replaceNodeData (self , key , value , lc , rc ):
35+ self .key = key
36+ self .payload = value
37+ self .leftChild = lc
38+ self .rightChild = rc
39+ if self .hasLeftChild ():
40+ self .leftChild .parent = self
41+ if self .hasRightChild ():
42+ self .rightChild .parent = self
43+
44+ class BinarySearchTree :
45+ def __init__ (self ):
46+ self .root = None
47+ self .size = 0
48+
49+ def length (self ):
50+ return self .size
51+
52+ def __len__ (self ):
53+ return self .size
54+
55+ def __iter__ (self ):
56+ return self .root .__iter__ ()
57+
58+ def put (self , key , val ):
59+ if self .root :
60+ self ._put (key , val , self .root )
61+ else :
62+ self .root = TreeNode (key , val )
63+ self .size = self .size + 1
64+
65+ def _put (self , key , val , currentNode ):
66+ if key < currentNode .key :
67+ if currentNode .hasLeftChild ():
68+ self ._put (key , val , currentNode .leftChild )
69+ else :
70+ currentNode .leftChild = TreeNode (key , val , parent = currentNode )
71+ self .updateBalance (currentNode .leftChild )
72+ else :
73+ if currentNode .hasRightChild ():
74+ self ._put (key , val , currentNode .rightChild )
75+ else :
76+ currentNode .rightChild = TreeNode (key , val , parent = currentNode )
77+ self .updateBalance (currentNode .rightChild )
78+
79+ def updateBalance (self , node ):
80+ if node .balanceFactor > 1 or node .balanceFactor < - 1 :
81+ self .rebalance (node )
82+ return
83+ if node .parent != None :
84+ if node .isLeftChild ():
85+ node .parent .balanceFactor += 1
86+ elif node .isRightChild ():
87+ node .parent .balanceFactor -= 1
88+
89+ if node .parent .balanceFactor != 0 :
90+ self .updateBalance (node .parent )
91+
92+ def rotateLeft (self , rotRoot ):
93+ newRoot = rotRoot .rightChild
94+ rotRoot .rightChild = newRoot .leftChild
95+ if newRoot .leftChild != None :
96+ newRoot .leftChild .parent = rotRoot
97+ newRoot .parent = rotRoot .parent
98+ if rotRoot .isRoot ():
99+ self .root = newRoot
100+ else :
101+ if rotRoot .isLeftChild ():
102+ rotRoot .parent .leftChild = newRoot
103+ else :
104+ rotRoot .parent .rightChild = newRoot
105+ newRoot .leftChild = rotRoot
106+ rotRoot .parent = newRoot
107+ rotRoot .balanceFactor = rotRoot .balanceFactor + 1 - min (newRoot .balanceFactor , 0 )
108+ newRoot .balanceFactor = newRoot .balanceFactor + 1 + max (rotRoot .balanceFactor , 0 )
109+
110+ def rotateRight (self , rotRoot ):
111+ newRoot = rotRoot .leftChild
112+ rotRoot .leftChild = newRoot .rightChild
113+ if newRoot .rightChild != None :
114+ newRoot .rightChild .parent = rotRoot
115+ newRoot .parent = rotRoot .parent
116+ if rotRoot .isRoot ():
117+ self .root = newRoot
118+ else :
119+ if rotRoot .isRightChild ():
120+ rotRoot .parent .rightChild = newRoot
121+ else :
122+ rotRoot .parent .rightChild = newRoot
123+ newRoot .rightChild = rotRoot
124+ rotRoot .parent = newRoot
125+ rotRoot .balanceFactor = rotRoot .balanceFactor + 1 - min (newRoot .balanceFactor , 0 )
126+ newRoot .balanceFactor = newRoot .balanceFactor + 1 + max (rotRoot .balanceFactor , 0 )
127+
128+ def rebalance (self , node ):
129+ if node .balanceFactor < 0 :
130+ if node .rightChild .balanceFactor > 0 :
131+ self .rotateRight (node .rightChild )
132+ self .rotateLeft (node )
133+ else :
134+ self .rotateLeft (node )
135+ elif node .balanceFactor > 0 :
136+ if node .leftChild .balanceFactor < 0 :
137+ self .rotateLeft (node .leftChild )
138+ self .rotateRight (node )
139+ else :
140+ self .rotateRight (node )
141+
142+ def __setitem__ (self , k , v ):
143+ self .put (k , v )
144+
145+ def get (self , key ):
146+ if self .root :
147+ res = self ._get (key , self .root )
148+ if res :
149+ return res .payload
150+ else :
151+ return None
152+ else :
153+ return None
154+
155+ def _get (self , key , currentNode ):
156+ if not currentNode :
157+ return None
158+ elif currentNode .key == key :
159+ return currentNode
160+ elif key < currentNode .key :
161+ return self ._get (key , currentNode .leftChild )
162+ else :
163+ return self ._get (key , currentNode .rightChild )
164+
165+ def __getitem__ (self , key ):
166+ return self .get (key )
167+
168+ def __contains__ (self , key ):
169+ if self ._get (key , self .root ):
170+ return True
171+ else :
172+ return False
173+
174+ def delete (self , key ):
175+ if self .size > 1 :
176+ nodeToRemove = self ._get (key , self .root )
177+ if nodeToRemove :
178+ self .remove (nodeToRemove )
179+ self .size -= 1
180+ else :
181+ raise KeyError ('Error, key not in tree' )
182+ elif self .size == 1 and self .root .key == key :
183+ self .root = None
184+ self .size = self .size - 1
185+ else :
186+ raise KeyError ('Error, key not in tree' )
187+
188+ def __delitem__ (self , key ):
189+ self .delete (key )
190+
191+ def spliceOut (self ):
192+ if self .isLeaf ():
193+ if self .isLeftChild ():
194+ self .parent .leftChild = None
195+ else :
196+ self .parent .rightChild = None
197+ elif self .hasAnyChildren ():
198+ if self .hasLeftChild ():
199+ if self .isLeftChild ():
200+ self .parent .leftChild = self .leftChild
201+ else :
202+ self .parent .rightChild = self .leftChild
203+ self .leftChild .parent = self .parent
204+ else :
205+ if self .isLeftChild ():
206+ self .parent .leftChild = self .rightChild
207+ else :
208+ self .parent .rightChild = self .rightChild
209+ self .rightChild .parent = self .parent
210+
211+ def findSuccessor (self ):
212+ succ = None
213+ if self .hasRightChild ():
214+ succ = self .rightChild .findMin ()
215+ else :
216+ if self .parent :
217+ if self .isLeftChild ():
218+ succ = self .parent
219+ else :
220+ self .parent .rightChild = None
221+ succ = self .parent .findSuccessor ()
222+ self .parent .rightChild = self
223+ return succ
224+
225+ def findMin (self ):
226+ current = self
227+ while current .hasLeftChild ():
228+ current = current .leftChild
229+ return current
230+
231+ def remove (self , currentNode ):
232+ if currentNode .isLeaf (): # leaf
233+ if currentNode == currentNode .parent .leftChild :
234+ currentNode .parent .leftChild = None
235+ else :
236+ currentNode .parent .rightChild = None
237+ elif currentNode .hasBothChildren (): # interior
238+ succ = currentNode .findSuccessor ()
239+ succ .spliceOut ()
240+ currentNode .key = succ .key
241+ currentNode .payload = succ .payload
242+
243+ else : # this node has one child
244+ if currentNode .hasLeftChild ():
245+ if currentNode .isLeftChild ():
246+ currentNode .leftChild .parent = currentNode .parent
247+ currentNode .parent .leftChild = currentNode .leftChild
248+ elif currentNode .isRightChild ():
249+ currentNode .leftChild .parent = currentNode .parent
250+ currentNode .parent .rightChild = currentNode .leftChild
251+ else :
252+ currentNode .replaceNodeData (currentNode .leftChild .key ,
253+ currentNode .leftChild .payload ,
254+ currentNode .leftChild .leftChild ,
255+ currentNode .leftChild .rightChild )
256+ else :
257+ if currentNode .isLeftChild ():
258+ currentNode .rightChild .parent = currentNode .parent
259+ currentNode .parent .leftChild = currentNode .rightChild
260+ elif currentNode .isRightChild ():
261+ currentNode .rightChild .parent = currentNode .parent
262+ currentNode .parent .rightChild = currentNode .rightChild
263+ else :
264+ currentNode .replaceNodeData (currentNode .rightChild .key ,
265+ currentNode .rightChild .payload ,
266+ currentNode .rightChild .leftChild ,
267+ currentNode .rightChild .rightChild )
268+
269+
270+
271+ mytree = BinarySearchTree ()
272+ mytree [3 ]= "red"
273+ mytree [4 ]= "blue"
274+ mytree [6 ]= "yellow"
275+ mytree [2 ]= "at"
276+
277+ print (mytree [6 ])
278+ print (mytree [2 ])
0 commit comments