-
Notifications
You must be signed in to change notification settings - Fork 134
/
MaxHeap.py
106 lines (84 loc) · 3.28 KB
/
MaxHeap.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
"""A max heap is a complete binary tree [CBT] (implemented using array)
in which each node has a value larger than its sub-trees"""
from math import ceil
class MaxHeap:
def __init__(self, arr=None):
self.heap = []
self.heap_size = 0
if arr is not None:
self.create_max_heap(arr)
self.heap = arr
self.heap_size = len(arr)
def create_max_heap(self, arr):
"""
Converts a given array into a max heap
:param arr: input array of numbers
"""
n = len(arr)
# last n/2 elements will be leaf nodes (CBT property) hence already max heaps
# loop from n/2 to 0 index and convert each index node into max heap
for i in range(int(n / 2), -1, -1):
self.max_heapify(i, arr, n)
def max_heapify(self, indx, arr, size):
"""
Assuming sub trees are already max heaps, converts tree rooted at current indx into a max heap.
:param indx: Index to check for max heap
"""
# Get index of left and right child of indx node
left_child = indx * 2 + 1
right_child = indx * 2 + 2
largest = indx
# check what is the largest value node in indx, left child and right child
if left_child < size:
if arr[left_child] > arr[largest]:
largest = left_child
if right_child < size:
if arr[right_child] > arr[largest]:
largest = right_child
# if indx node is not the largest value, swap with the largest child
# and recursively call min_heapify on the respective child swapped with
if largest != indx:
arr[indx], arr[largest] = arr[largest], arr[indx]
self.max_heapify(largest, arr, size)
def insert(self, value):
"""
Inserts an element in the max heap
:param value: value to be inserted in the heap
"""
self.heap.append(value)
self.heap_size += 1
indx = self.heap_size - 1
# Get parent index of the current node
parent = int(ceil(indx / 2 - 1))
# Check if the parent value is smaller than the newly inserted value
# if so, then replace the value with the parent value and check with the new parent
while parent >= 0 and self.heap[indx] > self.heap[parent]:
self.heap[indx], self.heap[parent] = self.heap[parent], self.heap[indx]
indx = parent
parent = int(ceil(indx / 2 - 1))
def delete(self, indx):
"""
Deletes the value on the specified index node
:param indx: index whose node is to be removed
:return: Value of the node deleted from the heap
"""
if self.heap_size == 0:
print("Heap Underflow!!")
return
self.heap[-1], self.heap[indx] = self.heap[indx], self.heap[-1]
self.heap_size -= 1
self.max_heapify(indx, self.heap, self.heap_size)
return self.heap.pop()
def extract_max(self):
"""
Extracts the maximum value from the heap
:return: extracted max value
"""
return self.delete(0)
def print(self):
print(*self.heap)
heap = MaxHeap([5, 10, 4, 8, 3, 0, 9, 11])
heap.insert(15)
print(heap.delete(2))
print(heap.extract_max())
heap.print()