-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathbinary_heap.py
150 lines (130 loc) · 4.45 KB
/
binary_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
# assign HEAP.MAX for a maxHeap
# if nothing is assigned, then heap is automatically MIN
class Heap:
MIN = "min"
MAX = "max"
# Time Complexity --> O(1)
# Space Complexity --> O(n)
def __init__(self, size, heapType = MIN):
super().__init__()
self.items = (size+1) * [None]
self.heapSize = 0
self.maxSize = size + 1
self.heapType = heapType
# Time Complexity --> O(1)
# Space Complexity --> O(1)
def peek(self):
if self.heapSize == 0:
return
else:
return self.items[1]
# Time Complexity --> O(1)
# Space Complexity --> O(1)
def size(self):
if self.items is None:
print("Heap doesn't exist")
return None
else:
return self.heapSize
# Time Complexity --> O(n)
# Space Complexity --> O(1)
def levelOrderTraversal(self):
if self.items is None:
print("Heap doesn't exist")
else:
for i in range(1, self.heapSize+1):
print(self.items[i])
def swap(self, index, parentIndex):
temp = self.items[index]
self.items[index] = self.items[parentIndex]
self.items[parentIndex] = temp
def heapifyInsert(self, index):
parentIndex = int(index/2)
if index <= 1:
return
if self.heapType == self.MIN:
if self.items[index] < self.items[parentIndex]:
self.swap(index, parentIndex)
else:
if self.items[index] > self.items[parentIndex]:
self.swap(index, parentIndex)
self.heapifyInsert(parentIndex)
def insertNode(self, nodeValue):
if self.heapSize + 1 == self.maxSize:
print("Heap is Full")
return
self.items[self.heapSize + 1] = nodeValue
self.heapSize += 1
self.heapifyInsert(self.heapSize)
def heapifyExtract(self, index):
leftIndex = index * 2
rightIndex = index * 2 + 1
swapChild = 0
if self.heapSize < leftIndex:
return
elif self.heapSize == leftIndex:
if self.heapType == self.MIN:
if self.items[index] > self.items[leftIndex]:
self.swap(index, leftIndex)
return
else:
if self.items[index] < self.items[leftIndex]:
self.swap(index, leftIndex)
return
else:
if self.heapType == self.MIN:
if self.items[leftIndex] < self.items[rightIndex]:
swapChild = leftIndex
else:
swapChild = rightIndex
if self.items[index] > self.items[swapChild]:
self.swap(index, swapChild)
else:
if self.items[leftIndex] > self.items[rightIndex]:
swapChild = leftIndex
else:
swapChild = rightIndex
if self.items[index] < self.items[swapChild]:
self.swap(index, swapChild)
self.heapifyExtract(swapChild)
def extractNode(self):
if self.heapSize == 0:
return
else:
# extract first node from tree
extractedNode = self.items[1]
# replace first node with last node
self.items[1] = self.items[self.heapSize]
# set last node's position to None
self.items[self.heapSize] = None
# reduce size of heap
self.heapSize -= 1
# execute heapifyExtract to shuffle everything into the right place
self.heapifyExtract( 1)
# return the extracted node
return extractedNode
def deleteEntireBP(self):
self.items = None
maxHeap = Heap(10, Heap.MIN)
maxHeap.insertNode(5)
maxHeap.insertNode(1)
# print("Extracted: ", maxHeap.extractNode())
print("--- Level Order Traversal After Insert---")
maxHeap.levelOrderTraversal()
print("\n\n")
# maxHeap.insertNode(18)
# maxHeap.insertNode(11)
# maxHeap.insertNode(19)
# maxHeap.insertNode(12)
# maxHeap.insertNode(20)
# maxHeap.insertNode(14)
# maxHeap.insertNode(48)
# print("--- Level Order Traversal After Insert---")
# maxHeap.levelOrderTraversal()
# print("\n\n")
# print("--- Extracting Node from heap ---")
# print("Extracted: ", maxHeap.extractNode())
# print("\n")
# print("--- Level Order Traversal After Extracting Node---")
# maxHeap.levelOrderTraversal()
# print("\n\n")