Faaez Razeen

Binary Heap

  • 3 min read
  • Binary Heap
  • Data Structure

3 years ago

class MinHeap: def __init__(self): self.values = [None] self.size = 0 # Could've used len(self.values) but this is smaller and # also more easier to understand due to the fact that we have a dummy value at the 0th index def perc_up(self, idx): ''' Conditionally swaps a node with its parent upwards to the appropriate position to maintain the heap order property ''' while idx // 2: if self.values[idx] < self.values[idx // 2]: self.values[idx], self.values[idx // 2] = self.values[idx // 2], self.values[idx] idx //= 2 def insert(self, value): ''' When a new value is inserted, it is added to the end of the list and percolated up the it's appropriate position. ''' self.values.append(value) self.size += 1 self.perc_up(self.size) def get_min_child_idx(self, idx): ''' Returns the index of child with the smaller value. ''' if idx * 2 + 1 > self.size: # If no right child, return left child return idx * 2 if self.values[idx * 2] < self.values[idx * 2 + 1]: # Return left child if it is smaller return idx * 2 return idx * 2 + 1 def perc_down(self, idx): ''' When the minimum value (at the root) is removed, the last child in the tree is swapped with the root, and percolated down to its appropriate position. If you're wondering why this function doesn't check for whether or not a left child exists, it's because this function will never be called on a child node. ''' while idx * 2 <= self.size: min_child_idx = self.get_min_child_idx(idx) if self.values[idx] > self.values[min_child_idx]: self.values[idx], self.values[min_child_idx] = self.values[min_child_idx], self.values[idx] idx = min_child_idx def del_min(self): ''' Returns the node with the smallest value in the heap. This messes up the heap order property, so further processing is done once the node is removed to maintain the sanctity of the holy binary heap. ''' return_value = self.values[1] self.values[1] = self.values[-1] self.size -= 1 self.values.pop() self.perc_down(1) return return_value def build_heap(self, values): ''' Builds a new heap from a list of values. We initialize an entire list to self.values, and starting from the middle and work our way up towards the root. from the middle because ''' i = len(values) // 2 self.values = [0] + values[:] while i: self.perc_down(i) i -= 1