PrepStack · Markdown HTML

K-way merge heap

Heap, selection, and stream · HTML

Formal shape

For m nondecreasing sequences S_j, store the first unconsumed entry (value,j,pos) from every nonempty source. Pop the global minimum and advance only that source.

Recognition signals

False friends

SignalWhy it is different
Internally unsorted sourcesA source can hide a smaller item behind its head; sort each source first or use a general selection method.
General graph shortest pathsDijkstra relaxes shared states reached by multiple routes; K-way merge follows fixed, non-merging ordered chains.
Only two in-memory arraysA two-pointer merge is linear with a smaller constant and needs no heap.

Core invariant

The heap contains exactly the first unconsumed item of every source that still has data; the global minimum unconsumed item is therefore in the heap.

State, transition, and processing order

ItemDefinition
StateA min-heap of size at most m with entries (key, source_id, source_position).
TransitionPop one head as the next output, advance that source by one, and push its new head if it exists.
Frontier / orderThe set of heads of m ordered chains; only the chain that just won is expanded.

Python skeleton

from heapq import heappop, heappush

def merge_sorted(sources):
    heap = []
    for sid, seq in enumerate(sources):
        if seq:
            heappush(heap, (seq[0], sid, 0))
    out = []
    while heap:
        value, sid, pos = heappop(heap)
        out.append(value)
        pos += 1
        if pos < len(sources[sid]):
            heappush(heap, (sources[sid][pos], sid, pos))
    return out

Correctness sketch

  1. Within one ordered source, its head is its smallest unconsumed item.
  2. The minimum over all unconsumed items is consequently the minimum over source heads, which heap pop returns.
  3. Only the winning source loses its head; advancing that source alone restores the invariant.

Complexity

TimeSpaceParameters
O(N log m) for N outputs, or O(m+t log m) for a t-item prefixO(m), excluding outputm is the source count, N the total size, and t the consumed prefix.

Edge cases

Error patterns

PatternWhy it fails / fix
Pushing every source elementThis grows the heap to O(N) and discards the main frontier compression.
Advancing every sourceOnly the winner lost its head; advancing other sources skips valid output.
Omitting source identityAfter a pop there is no way to know which chain to advance. Carry an id and position or iterator.

Selection and exclusion rules

RelationTemplateBoundary
compositionLinked-list pointer rewiringA heap selects linked-list heads while pointer rewiring builds the output.
contrastTop-K bounded heapTop-K evicts candidates; K-way merge preserves one next candidate per source.

Original micro-example

PartDetail
ResultThe output is [1,2,3,5,7,8], and the heap never exceeds three entries.
SetupThree timestamp streams are [1,8], [2,3], and [5,7].
TraceHeads 1,2,5 enter the heap. After popping 1, only 8 is added; then 2,3,5,7,8 follow.

Recall prompts

My notes