-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmin_heap.py
157 lines (138 loc) · 4.6 KB
/
min_heap.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
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
from collections import deque
class TreeNode(object):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
class MinHeap(object):
def __init__(self):
self.root = None
def isNodeFull(self, node):
if node.left and node.right:
return True
return False
def insert(self, val):
node = TreeNode(val)
if self.root is None:
self.root = node
else:
parentQ = deque()
curr = self.root
while True:
parentQ.append(curr)
if curr.left is None:
curr.left = node
break
if curr.right is None:
curr.right = node
break
if self.isNodeFull(curr.left) and not self.isNodeFull(curr.right):
curr = curr.right
else:
curr = curr.left
self.siftUp(parentQ)
def siftUp(self, parentQ):
while parentQ:
parent = parentQ.pop()
child = None
if parent.left and parent.left.val < parent.val:
child = parent.left
if parent.right and parent.right.val < parent.val:
child = parent.right
if child:
temp = parent.val
parent.val = child.val
child.val = temp
def popLastNode(self):
nodeQ = deque()
nodeQ.append(self.root)
prevNode = None
while True:
if not nodeQ:
if prevNode:
if self.isNodeFull(prevNode):
prevNode.right = None
else:
prevNode.left = None
break
lastNode = nodeQ.popleft()
if lastNode.left:
nodeQ.append(lastNode.left)
if lastNode.right:
nodeQ.append(lastNode.right)
if lastNode.left or lastNode.right:
prevNode = lastNode
return lastNode
def delMin(self):
if self.root.left and self.root.right:
lastNode = self.popLastNode()
self.root.val = lastNode.val
curr = self.root
else:
self.root = None
return
while True:
child = None
if curr.left is None and curr.right is None:
break
if self.isNodeFull(curr):
if curr.val < curr.left.val and curr.val < curr.right.val:
break
if curr.left.val < curr.right.val:
child = curr.left
else:
child = curr.right
elif curr.left and curr.left.val < curr.val:
child = curr.left
else:
child = curr.right
if child:
temp = curr.val
curr.val = child.val
child.val = temp
curr = child
else:
break
def siftDown(self):
pass
def show(self, method="inorder"):
if method == "inorder":
traversal = self._inOrderTraversal
elif method == "preorder":
traversal = self._preOrderTraversal
elif method == "postorder":
traversal = self._postOrderTraversal
result = []
result = traversal(self.root, result)
print([node.val for node in result])
def _preOrderTraversal(self, rootNode, result=[]):
if rootNode:
result.append(rootNode)
self._preOrderTraversal(rootNode.left, result)
self._preOrderTraversal(rootNode.right, result)
return result
def _postOrderTraversal(self, rootNode, result=[]):
if rootNode:
self._postOrderTraversal(rootNode.left, result)
self._postOrderTraversal(rootNode.right, result)
result.append(rootNode)
return result
def _inOrderTraversal(self, rootNode, result=[]):
if rootNode:
self._inOrderTraversal(rootNode.left, result)
result.append(rootNode)
self._inOrderTraversal(rootNode.right, result)
return result
if __name__ == "__main__":
minHeap = MinHeap()
dataList = [4, 6, 2, 10, 12, 14, 16, 1]
# dataList = [16, 12, 14]
for data in dataList:
minHeap.insert(data)
minHeap.show()
for data in dataList:
minHeap.delMin()
# minHeap.show()
print("{} ".format(minHeap.root.val), end="")
# print()
# break