Heap
Binary Heap
- used in HeapSort
- it is a complete binary tree
- used to implement Priority Queue
- 2 types: Min heap; Max heap
Min Heap(highest priority item assigned lowest value)Max Heap(highest priority item assigned highest value)
heapq
- Python
import heapq
pq = [5, 20, 1, 30, 4]
heapq.heapify(pq) # 1,4,5,30,20
heapq.heappush(pq, 3) # 1,4,3,30,20,5
m = heapq.heappop(pq) # 3,4,5,30,20 (removes min element)
heapq.nlargest(2, pq) # [30,20]
heapq.nsmallest(2, pq) # [1,4]
heapq.pushpop(pq, 2)
heapq.heapreplace(pq, -1)
note
Python implements heapq as min heap. To implement max heap multiply elements by -1 before storing
Min Heap
- complete binary tree
- every node has value smaller than it's descendants
- Array implementation:
parent = (i-1) // 2left = 2i + 1right = 2i + 2
- Python
class MinHeap:
def __init__(self):
self.mh = []
def __init__(self, arr = []):
self.mh = arr
# bottom left internal node
i = self.parent(len(arr) - 1)
while i >= 0:
self.minHeapify(i)
i -= 1
def parent(self, i):
return (i - 1) // 2
def left(self, i):
return 2 * i + 1
def right(self, i):
return 2 * i + 2
def insert(self, x):
self.mh.append(x)
i = len(self.mh) - 1
while i > 0 and self.mh[self.parent(i)] > self.mh[i]:
p = self.parent(i)
self.mh[i], self.mh[p] = self.mh[p], self.mh[i]
i = p
def minHeapify(self, i):
# fixes the heap whose root is violating the heap properties
l = self.left(i)
r = self.right(i)
smallest = i
n = len(self.mh)
if l < n and self.mh[l] < self.mh[smallest]:
smallest = l
if r < n and self.mh[r] < self.mh[smallest]:
smallest = r
if smallest != i:
self.mh[smallest], self.mh[i] = self.mh[i], self.mh[smallest]
self.minHeapify(smallest)
def extractMin(self):
n = len(self.mh)
if n == 0:
return float("inf")
res = self.mh[0]
self.mh[0] = self.mh[n - 1]
self.mh.pop()
self.minHeapify(0)
return res
def decreaseKey(self, i, x):
self.mh[i] = x
while i != 0 and self.mh[self.parent(i)] > self.mh[i]:
p = self.parent(i)
self.mh[i], self.mh[p] = self.mh[p], self.mh[i]
i = p
def deleteKey(self, i):
n = len(self.mh)
if i >= n:
return
self.decreaseKey(i, float("-inf"))
self.extractMin()