Skip to content
Cannot retrieve contributors at this time
128 lines (97 sloc) 3.58 KB
""" - implementation of a heap priority queue. """
__author__ = "Caleb Madrigal"
__date__ = "2015-02-17"
import math
from enum import Enum
from autoresizelist import AutoResizeList
class HeapType(Enum):
maxheap = 1
minheap = 2
class Heap:
def __init__(self, initial_data=None, heap_type=HeapType.maxheap):
self.heap_type = heap_type
if heap_type == HeapType.maxheap:
self.comparator = lambda x, y: x > y
self.comparator = lambda x, y: x < y = AutoResizeList()
if initial_data is not None:
self._size = len(
def _left_child(self, index):
return 2*index + 1
def _right_child(self, index):
return 2*index + 2
def _parent(self, index):
return math.floor((index - 1) / 2.0)
def _is_root(self, index):
return index == 0
def _swap(self, i1, i2):[i1],[i2] =[i2],[i1]
def build_heap(self, initial_data):
for i in initial_data:
def heap_up(self, index):
# If we are at the root, return - we are done
if self._is_root(index):
# Else, compare the current node with the parent node, and if this node should be higher
# then the parent node, then swap and recursively call on the parent index
parent_index = self._parent(index)
if self.comparator([index],[parent_index]):
self._swap(index, parent_index)
def heap_down(self, index):
left_index = self._left_child(index)
right_index = self._right_child(index)
left =[left_index]
except IndexError:
left = None
right =[right_index]
except IndexError:
right = None
# Find the largest child
largest_child = left
largest_child_index = left_index
if left is not None and right is not None:
if self.comparator(right, left):
largest_child = right
largest_child_index = right_index
elif right is not None:
largest_child = right
largest_child_index = right_index
# If the largest child is not None and is higher priority than the current, then swap
# and recursively call on on the child index
if largest_child is not None and self.comparator(largest_child,[index]):
self._swap(index, largest_child_index)
def push(self, item):
insert_index = self._size # Insert at the end
self._size += 1[insert_index] = item
return self
def peek(self):
def pop(self):
if len( < 1 or[0] is None:
return None
# Take item from the root
item =[0]
# Move the bottom-most, right-most item to the root[0] =[self._size-1][self._size-1] = None
self._size -= 1
return item
def size(self):
return self._size
def __repr__(self):
return str(
if __name__ == "__main__":
import unittest
testsuite = unittest.TestLoader().discover('test', pattern="*heap*")