#!/usr/bin/env python class PriorityQueue(object): def __init__(self, compare=cmp): self.pq = [] self.n = 0 self.compare = compare def insert(self, element): self.swim(element) def remove(self): if self.n == 0: return None e = self.pq[0] self.sink() return e def elements(self): return [self.pq[i] for i in xrange(0, self.n)] def swim(self, element): self.n += 1 if len(self.pq) >= self.n: self.pq[self.n-1] = element else: self.pq.append(element) current_pos = self.n parent_pos = current_pos / 2 # python uses 0-based index, hence always minus the position by 1 while (self.compare(self.pq[current_pos-1], self.pq[parent_pos-1]) > 0 and current_pos > 1): self.pq[current_pos-1], self.pq[parent_pos-1] = (self.pq[parent_pos-1], self.pq[current_pos-1]) current_pos = parent_pos parent_pos = current_pos / 2 def sink(self): current_pos = 1 # since it's a binary heap, a parent can only have max 2 children self.pq[current_pos-1] = self.pq[self.n-1] self.n -= 1 child_pos = self.get_child_position(current_pos) if child_pos == -1: return while self.compare(self.pq[child_pos-1], self.pq[current_pos-1]) > 0: self.pq[child_pos-1], self.pq[current_pos-1] = (self.pq[current_pos-1], self.pq[child_pos-1]) current_pos = child_pos child_pos = self.get_child_position(current_pos) if child_pos == -1: break def get_child_position(self, current_pos): first_child_pos = 2 * current_pos second_child_pos = (2 * current_pos) + 1 child_pos = -1 # no child # no child if first_child_pos > self.n: return child_pos # there's only one child if second_child_pos > self.n: child_pos = first_child_pos else: # there are two children if self.compare(self.pq[first_child_pos-1], self.pq[second_child_pos-1]) > 0: child_pos = first_child_pos else: child_pos = second_child_pos return child_pos def size(self): return self.n def min_compare(x, y): if x < y: return 1 elif x == y: return 0 else: return -1 if __name__ == "__main__": pq = PriorityQueue() pq.insert(4) pq.insert(5) pq.insert(1) pq.insert(8) pq.insert(2) pq.insert(3) pq.insert(10) pq.insert(7) pq.insert(9) pq.insert(6) assert 10 == pq.remove() assert 9 == pq.remove() assert 8 == pq.remove() assert 7 == pq.remove() assert 6 == pq.remove() assert 5 == pq.remove() assert 4 == pq.remove() assert 3 == pq.remove() assert 2 == pq.remove() assert 1 == pq.remove() pq.insert(4) pq.insert(5) assert 5 == pq.remove() assert 4 == pq.remove() assert None == pq.remove() pq.insert(4) pq.insert(5) pq.insert(1) pq.insert(8) pq.insert(2) pq.insert(3) pq.insert(10) pq.insert(7) pq.insert(9) pq.insert(6) assert 10 == pq.remove() assert 9 == pq.remove() assert 8 == pq.remove() assert 7 == pq.remove() assert 6 == pq.remove() assert 5 == pq.remove() assert 4 == pq.remove() assert 3 == pq.remove() assert 2 == pq.remove() assert 1 == pq.remove() pq = PriorityQueue(min_compare) pq.insert(4) pq.insert(5) pq.insert(1) pq.insert(8) pq.insert(2) pq.insert(3) pq.insert(10) pq.insert(7) pq.insert(9) pq.insert(6) assert 1 == pq.remove() assert 2 == pq.remove() assert 3 == pq.remove() assert 4 == pq.remove() assert 5 == pq.remove() assert 6 == pq.remove() assert 7 == pq.remove() assert 8 == pq.remove() assert 9 == pq.remove() assert 10 == pq.remove() pq.insert(4) pq.insert(5) assert 4 == pq.remove() assert 5 == pq.remove() assert None == pq.remove() pq.insert(4) pq.insert(5) pq.insert(1) pq.insert(8) pq.insert(2) pq.insert(3) pq.insert(10) pq.insert(7) pq.insert(9) pq.insert(6) assert 1 == pq.remove() assert 2 == pq.remove() assert 3 == pq.remove() assert 4 == pq.remove() assert 5 == pq.remove() assert 6 == pq.remove() assert 7 == pq.remove() assert 8 == pq.remove() assert 9 == pq.remove() assert 10 == pq.remove()
Sunday, April 22, 2012
How to Implement Priority Queue in Python
Below a simple implementation of priority queue using binary heap.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment