Just run a greedy search of the heap, interpreted as a general binary tree. The heap invariant means that when you know the smallest k
items of the heap, the k+1
th-smallest must be one of their children. You can build a second heap of all candidates for the next-smallest item, and that heap will never grow beyond O(log(n))
, so insertions and deletions take O(log(log(n))
, and you need O(log(n))
insertions and deletions in the second heap. This works for finding the smallest k
items of a heap in O(k*log(k))
time, regardless of what k
is.
Here's example code in Python:
import heapq
def smallestk(heap, k):
if not k:
return
candidates = [(heap[0], 0)]
for _ in xrange(k):
val, index = heapq.heappop(candidates)
yield val
for child in (2*index+1, 2*index+2):
if child < len(heap):
heapq.heappush(candidates, (heap[child], child))