def test_0(): # 0 # 1 2 3 # 4 5 6 7 8 9 10 11 12 heap = MinHeap(*range(13), n=3) assert heap.height == 3 assert heap.parent(0) is None assert heap.child(0, 0) == 1 assert heap.child(0, 1) == 2 assert heap.child(0, 2) == 3 assert heap.first(0) == 1 assert heap.last(0) == 3 assert heap.parent(1) == 0 assert heap.child(1, 0) == 4 assert heap.child(1, 1) == 5 assert heap.child(1, 2) == 6 assert heap.first(1) == 4 assert heap.last(1) == 6 assert heap.parent(2) == 0 assert heap.child(2, 0) == 7 assert heap.child(2, 1) == 8 assert heap.child(2, 2) == 9 assert heap.first(2) == 7 assert heap.last(2) == 9 assert heap.parent(3) == 0 assert heap.child(3, 0) == 10 assert heap.child(3, 1) == 11 assert heap.child(3, 2) == 12 assert heap.first(3) == 10 assert heap.last(3) == 12 assert heap.parent(4) == 1 assert heap.parent(5) == 1 assert heap.parent(6) == 1 assert heap.parent(7) == 2 assert heap.parent(8) == 2 assert heap.parent(9) == 2 assert heap.parent(10) == 3 assert heap.parent(11) == 3 assert heap.parent(12) == 3 assert heap.is_valid() assert tuple(heap.walk_up(4)) == ((1, 4), (0, 1)) assert tuple(heap.walk_up(5)) == ((1, 5), (0, 1)) assert tuple(heap.walk_up(6)) == ((1, 6), (0, 1)) assert tuple(heap.walk_up(7)) == ((2, 7), (0, 2)) assert tuple(heap.walk_up(12)) == ((3, 12), (0, 3)) assert tuple(heap.walk_down()) == ((0, 1), (1, 4)) heap.push(14) assert heap.is_valid() heap.push(6) assert heap.is_valid() assert heap.pop() == 0 assert heap.is_valid() assert heap.pop() == 1 assert heap.is_valid() assert heap.pop() == 2 assert heap.is_valid()
class PriorityQueue: def __init__(self): self.heap = MinHeap() def enqueue(self, priority, item): self.heap.push(PriorityQueueItem(priority, item)) def dequeue(self): try: return self.heap.pop().value except: return None
def sort(array): heap = MinHeap() for i in array: heap.push(i) out = [] while True: try: out.append(heap.pop()) except: break return out
class SinglePercentileTracker(object): ''' A class that tracks a single percentile''' def __init__(self, percentile): self.percentile_tracked = percentile self.lheap = MaxHeap() self.rheap = MinHeap() self.size = 0 self.percentile = None def add(self, num): # An addition to a list is O(log n) since look up is O(1) # insertions are O(log n), and worst case pop is O(log n) # and everything is done a constant number of times. In these # cases, n is the size of the larger of the two heaps self.size += 1 n = (self.percentile_tracked / 100.0) * (self.size + 1) # The left heap should always be the floor of n, so we have the # floor(n)th ranked node as the max node in the left heap, and the # min node of the right heap will be the nth+1 ranked node. lsize = int(math.floor(n)) # Push the num on to the proper heap if num > self.percentile: self.rheap.push(num) else: self.lheap.push(num) # if the left heap isn't the right size, push or pop the nodes # to make sure it is. if self.lheap.size() < lsize: self.lheap.push(self.rheap.pop()) elif self.lheap.size() > lsize: self.rheap.push(self.lheap.pop()) # Take the integer part of n and grab the nth and nth+1 # ranked nodes. Then take the nth node as the base # and add the fractional part of n * nth+1 ranked node to get a # weighted value between the two. This is your percentile. ir = int(n) fr = n - ir low_data = self.lheap.get(0) high_data = self.rheap.get(0) self.percentile = fr * (high_data - low_data) + low_data def add_list(self, lst): # Add list is O(k * log n) where k is len(lst) and n is # the size of the larger of the two heaps for l in lst: self.add(l)
class HeapMedian: ''' solution using min-, max- heaps ''' def __init__(self): self.upper = MinHeap() self.lower = MaxHeap() def add(self, i): assert self.lower.size() >= self.upper.size() if self.lower.size()==0 or\ i <= self.lower.peek(): self.lower.push(i) else: self.upper.push(i) if self.lower.size() < self.upper.size(): self.lower.push(self.upper.pop()) elif self.lower.size() > self.upper.size()+1: self.upper.push(self.lower.pop()) def get(self): return self.lower.peek()