08-heaps
Top-K with a Heap
Keep only the largest k values by maintaining a small min-heap.
Algorithm
Steps
- Store the heap in an array.
- Compare parent and child indexes instead of building explicit tree nodes.
- Swap only when the heap order is violated.
- Print the deterministic final heap state for replay comparison.
Complexity
- Time: O(n log k)
- Space: O(k)
bounded heap
For top-k largest values, a min-heap of size k keeps the current cutoff at the root.
Scala DSA Implementation
basic.scala
import scala.collection.mutable.ArrayBuffer
object Main {
def listString(values: Seq[Int]): String = values.mkString("[", ", ", "]")
def heapInsert(heap: ArrayBuffer[Int], value: Int): Unit = {
heap += value
var child = heap.length - 1
while (child > 0) {
val parent = (child - 1) / 2
if (heap(parent) <= heap(child)) return
val tmp = heap(parent); heap(parent) = heap(child); heap(child) = tmp
child = parent
}
}
def heapPop(heap: ArrayBuffer[Int]): Int = {
val smallest = heap(0)
heap(0) = heap.remove(heap.length - 1)
var parent = 0
var done = false
while (!done) {
val left = parent * 2 + 1
val right = left + 1
if (left >= heap.length) done = true
else {
var child = left
if (right < heap.length && heap(right) < heap(left)) child = right
if (heap(parent) <= heap(child)) done = true
else { val tmp = heap(parent); heap(parent) = heap(child); heap(child) = tmp; parent = child }
}
}
smallest
}
def main(args: Array[String]): Unit = { val heap = ArrayBuffer.empty[Int]; for (value <- List(5, 1, 9, 3, 7, 2)) { heapInsert(heap, value); if (heap.length > 3) heapPop(heap) }; println(listString(heap.sorted(Ordering.Int.reverse))) }
}
Implementation notes
- The working heap is a Scala mutable
ArrayBuffer[Int], starting fromArrayBuffer.empty[Int]. - The helper functions keep it as a min-heap, so the smallest kept top-k value
sits at index
0. for (value <- List(5, 1, 9, 3, 7, 2))considers values in that fixed order.- Each value is first passed through
heapInsert(heap, value), which appends and sifts up using parent indexes. - The size bound is the literal
3: after each insert,if (heap.length > 3) heapPop(heap)removes the current minimum. - That means low values can still be inserted briefly; the trace for
2ends back at[5, 7, 9]after the pop removes it. - The replayed heap states are
[5],[1, 5],[1, 5, 9],[3, 5, 9],[5, 7, 9], then[5, 7, 9]. - The heap array is not stored in sorted order, so
heap.sorted(Ordering.Int.reverse)is used only for output, producing[9, 7, 5].
Output
[9, 7, 5]