def __iter__(self):
try:
while True:
yield self.extract()
except IndexError:
return
return iter([])
这就是我目前正在尝试做的事情。我们的想法是枚举堆中的所有项目,并且必须在O(n)时间内运行。 上面提到的提取函数从堆中删除了最高优先级的项目。
这是实施的其余部分:
from copy import copy
class Heap:
"""
A heap-based priority queue
Items in the queue are ordered according to a comparison function
"""
def __init__(self, comp):
"""
Constructor
:param comp: A comparison function determining the priority of the included elements
"""
self.comp = comp
self.heap = []
self.size = len(self.heap)
def __len__(self):
return len(self.heap)
def peek(self):
if self.__len__() == 0:
raise IndexError
else:
return self.heap[0]
def insert(self, item):
pass
def _siftdown(self, startpos, pos):
newitem = self.heap[pos]
# Follow the path to the root, moving parents down until finding a place
# newitem fits.
while pos > startpos:
parentpos = (pos - 1) >> 1
parent = self.heap[parentpos]
if newitem < parent:
self.heap[pos] = parent
pos = parentpos
continue
break
self.heap[pos] = newitem
def siftup(self, pos):
endpos = len(self.heap)
startpos = pos
newitem = self.heap[pos]
# Bubble up the smaller child until hitting a leaf.
childpos = 2*pos + 1 # leftmost child position
while childpos < endpos:
# Set childpos to index of smaller child.
rightpos = childpos + 1
if rightpos < endpos and not self.heap[childpos] < self.heap[rightpos]:
childpos = rightpos
# Move the smaller child up.
self.heap[pos] = self.heap[childpos]
pos = childpos
childpos = 2*pos + 1
# The leaf at pos is empty now. Put newitem there, and bubble it up
# to its final resting place (by sifting its parents down).
self.heap[pos] = newitem
self.siftdown(self.heap, startpos, pos)
def heapify(self,heap,i):
l = (2*i) + 1
r = (2*i) + 2
if l < len(heap) and heap[l] < heap[i]:
small = l
else:
small = i
if r < len(heap) and heap[r] < heap[small]:
small = r
if small != i:
heap[i], heap[small] = heap[small], heap[i]
self.heapify(heap,small)
def extract(self):
if self.is_empty():
raise IndexError
minimum = self.heap[0]
self.heap[0] = self.heap[-1]
self.size -= 1
self.heapify(self.heap,0)
return minimum
def extend(self, seq):
pass
def clear(self):
pass
def __iter__(self):
try:
while True:
yield self.extract()
except IndexError:
return
return iter([])
def is_empty(self):
"""
Checks if this heap is empty
:return: True if the heap is empty
"""
return len(self.heap) == 0
def __bool__(self):
"""
Checks if this heap contains items
:return: True if the heap is non-empty
"""
return not self.is_empty()
def __repr__(self):
"""
A string representation of this heap
:return:
"""
return 'Heap([{0}])'.format(','.join(str(item) for item in self))
def find_median(seq):
"""
Finds the median (middle) item of the given sequence.
Ties are broken arbitrarily.
:param seq: an iterable sequence
:return: the median element
"""
if not seq:
raise IndexError
min_heap = Heap(lambda a, b: a <= b)
max_heap = Heap(lambda a, b: a >= b)
raise IndexError