Skip to content

Instantly share code, notes, and snippets.

@yxy
Created September 21, 2016 14:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yxy/fad14ff98c68dc1f7677943512ed8426 to your computer and use it in GitHub Desktop.
Save yxy/fad14ff98c68dc1f7677943512ed8426 to your computer and use it in GitHub Desktop.
Generic Maximum or Minimum Heap implemenation
class Heap(object):
def __init__(self, test_func):
self._data = []
self._pos = 0
self.test_func = test_func
def size(self):
return self._pos
def add(self, val):
self._data.append(val)
self._bubble_up()
self._pos += 1
def _bubble_up(self):
pos = self._pos
while pos > 0 and self.test(pos, (pos-1)//2):
self._swap(pos, (pos-1)//2)
pos = (pos-1) // 2
def top(self):
return self._data[0] if self.size() > 0 else None
def _pop(self, pos):
self._swap(pos, self._pos-1)
self._data.pop()
self._pos -= 1
self._sink_down(pos)
def pop(self):
v = self.top()
if v is not None:
self._pop(0)
return v
def _sink_down(self, pos):
l = 2*pos + 1
r = 2*pos + 2
n = pos
if l < self.size() and r < self.size():
n = l if self.test(l, r) else r
elif l < self.size():
n = l
elif r < self.size():
n = r
if n != pos and self.test(n, pos):
self._swap(n, pos)
self._sink_down(n)
def _swap(self, p1, p2):
self._data[p1], self._data[p2] = self._data[p2], self._data[p1]
def test(self, x, y):
return self.test_func(self._data[x], self._data[y])
def at(self, val):
"""return val the pos for pop usage"""
queue = [[0]]
while queue:
idxes = queue.pop()
for idx in idxes:
if self._data[idx] == val:
return idx
to_add = []
ll = [idx*2 + 1, idx*2 + 2]
for x in ll:
if x >= self.size() or self.test_func(val, self._data[x]):
continue
to_add.append(x)
if to_add:
queue.insert(0, to_add)
return None
def remove(self, val):
pos = self.at(val)
if pos is not None:
self._pop(pos)
return True
return False
MaxHeap = Heap(lambda x, y: x > y)
MinHeap = Heap(lambda x, y: x < y)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment