Skip to content

Commit c25c85d

Browse files
tree!
1 parent bdcc80a commit c25c85d

9 files changed

Lines changed: 853 additions & 102 deletions

File tree

.idea/workspace.xml

Lines changed: 129 additions & 83 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

AVL.py

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
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])

BinaryHeap.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# 构建树实现堆
2+
class BinHeap:
3+
def __init__(self):
4+
self.heapList = [0]
5+
self.currentSize = 0
6+
7+
#插入新结点后必要时交换子节点和父节点的位置保持堆的性质
8+
def percUp(self, i):
9+
while i//2 > 0:
10+
if self.heapList[i] < self.heapList[i//2]:
11+
temp = self.heapList[i//2]
12+
self.heapList[i//2] = self.heapList[i]
13+
self.heapList[i] = temp
14+
i = i//2
15+
16+
# 插入节点
17+
def insert(self, k):
18+
self.heapList.append(k)
19+
self.currentSize += 1
20+
self.percUp(self.currentSize)
21+
22+
# 删除堆顶元素后, 交换堆尾和空堆顶的位置并实现元素的下沉
23+
def percDown(self, i):
24+
while (i*2) <= self.currentSize:
25+
mc = self.minChild(i)
26+
if self.heapList[i] > self.heapList[mc]:
27+
temp = self.heapList[i]
28+
self.heapList[i] = self.heapList[mc]
29+
self.heapList[mc] = temp
30+
i = mc
31+
32+
def minChild(self, i):
33+
if i * 2 + 1 > self.currentSize:
34+
return i * 2
35+
else:
36+
if self.heapList[i*2] < self.heapList[i*2+1]:
37+
return i * 2
38+
else:
39+
return i * 2 + 1
40+
41+
def delMin(self):
42+
retval = self.heapList[1]
43+
self.heapList[1] = self.heapList[self.currentSize]
44+
self.currentSize = self.currentSize - 1
45+
self.heapList.pop()
46+
self.percDown(1)
47+
return retval
48+
49+
def buildHeap(self, alist):
50+
i = len(alist) // 2
51+
self.currentSize = len(alist)
52+
self.heapList = [0] + alist[:]
53+
while (i > 0):
54+
self.percDown(i)
55+
i = i - 1
56+
return self.heapList
57+
58+
H = BinHeap()
59+
print(H.buildHeap([9, 6, 5, 2, 3]))

0 commit comments

Comments
 (0)