Created
September 21, 2016 14:47
-
-
Save yxy/fad14ff98c68dc1f7677943512ed8426 to your computer and use it in GitHub Desktop.
Generic Maximum or Minimum Heap implemenation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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