Skip to content

Commit c3d14c4

Browse files
committed
More comments
1 parent e2e04f8 commit c3d14c4

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/k_smallest.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ where
4949

5050
// Rearrange the into a valid heap by reordering from the second-bottom-most layer up
5151
// Slightly faster than ordering on each insert, but only by a factor of lg(k)
52+
// The resulting heap has the **largest** item on top
5253
for i in (0..=(storage.len() / 2)).rev() {
5354
sift_down(&mut storage, &mut is_less_than, i);
5455
}
@@ -63,18 +64,23 @@ where
6364
// Treating this as an push-and-pop saves having to write a sift-up implementation
6465
// https://en.wikipedia.org/wiki/Binary_heap#Insert_then_extract
6566
storage[0] = val;
67+
// We retain the smallest items we've seen so far, but ordered largest first so we can drop the largest efficiently.
6668
sift_down(&mut storage, &mut is_less_than, 0);
6769
}
6870
});
6971
}
7072

71-
let mut heap = &mut storage[..];
73+
// Ultimately the items need to be in least-first, strict order, but the heap is currently largest-first.
74+
// To achieve this, repeatedly
75+
// 1) "pop" the largest item off the heap into the tail slot of the underlying storage
76+
// 2) shrink the logical size of the heap by 1
77+
// 3) restore the heap property over the remaining items
7278

79+
let mut heap = &mut storage[..];
7380
while heap.len() > 1 {
7481
let last_idx = heap.len() - 1;
7582
heap.swap(0, last_idx);
76-
// Leaves the length shorter than the number of elements
77-
// so that sifting does not disturb already popped elements
83+
// Sifting over a truncated slice means that the sifting will not disturb already popped elements
7884
heap = &mut heap[..last_idx];
7985
sift_down(heap, &mut is_less_than, 0);
8086
}

0 commit comments

Comments
 (0)