class MinHeap:
def __init__(self):
self.heap = []
def parent(self, i):
return (i - 1) // 2
def left_child(self, i):
return 2 * i + 1
def right_child(self, i):
return 2 * i + 2
def swap(self, i, j):
self.heap[i], self.heap[j] = self.heap[j], self.heap[i]
def insert(self, key):
self.heap.append(key)
self._sift_up(len(self.heap) - 1)
def _sift_up(self, i):
parent = self.parent(i)
if i > 0 and self.heap[i] < self.heap[parent]:
self.swap(i, parent)
self._sift_up(parent)
def extract_min(self):
if not self.heap:
raise IndexError("Heap is empty")
min_val = self.heap[0]
last_val = self.heap.pop()
if self.heap:
self.heap[0] = last_val
self._sift_down(0)
return min_val
def _sift_down(self, i):
min_idx = i
left = self.left_child(i)
right = self.right_child(i)
if left < len(self.heap) and self.heap[left] < self.heap[min_idx]:
min_idx = left
if right < len(self.heap) and self.heap[right] < self.heap[min_idx]:
min_idx = right
if min_idx != i:
self.swap(i, min_idx)
self._sift_down(min_idx)