Min-heap (priority queue) in Python
A min-heap keeps the smallest value at the front of a list, read as a tree where every parent is at most its children. Adding or taking out a value only repairs one path, so both take O(log n) steps.
The arrow keys step through it. Edit the code to try your own input.
How it works
- The list is read as a tree: the children of index
iare at2 * i + 1and2 * i + 2, and its parent is at(i - 1) // 2. pushadds the new value at the end, then swaps it with its parent while the parent is bigger: it sifts up.poptakesheap[0], the smallest value, moves the last value to the top, then swaps it with its smaller child until both children are bigger: it sifts down.- Python's
heapqmodule does the same withheapq.heappushandheapq.heappop, on a plain list.
What to watch
- Watch 1 sift up from the bottom to the top when it is pushed.
- Watch the tree after each push: every parent is at most its children, but the list itself is not sorted.
- Watch
childpick the smaller of the two children before each swap down.
The code
def push(heap, value): heap.append(value) # add at the bottom i = len(heap) - 1 while i > 0 and heap[(i - 1) // 2] > heap[i]: parent = (i - 1) // 2 heap[i], heap[parent] = heap[parent], heap[i] i = parent # move up the tree def pop(heap): smallest, last = heap[0], heap.pop() if heap: heap[0] = last # last value to the top i = 0 while 2 * i + 1 < len(heap): child = 2 * i + 1 if child + 1 < len(heap) and heap[child + 1] < heap[child]: child += 1 # the smaller child if heap[i] <= heap[child]: break heap[i], heap[child] = heap[child], heap[i] i = child # move down the tree return smallest heap = [] for value in [7, 3, 9, 1, 5, 2]: push(heap, value) print("Heap:", heap) print("Taken out:", pop(heap), pop(heap), pop(heap))
Output
Heap: [1, 3, 2, 7, 5, 9] Taken out: 1 2 3
Open it in the editor · Python Program to Implement a Priority Queue, explained