Skip to content

Commit fe5a8d8

Browse files
committed
Trying to clarify comparator
1 parent ba5d105 commit fe5a8d8

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

src/k_smallest.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ where
88
F: FnMut(&I::Item, &I::Item) -> Ordering,
99
{
1010
/// Sift the element currently at `origin` **away** from the root until it is properly ordered
11-
fn sift_down<T, F>(heap: &mut [T], comparator: &mut F, mut origin: usize)
11+
fn sift_down<T, F>(heap: &mut [T], is_less_than: &mut F, mut origin: usize)
1212
where
13-
F: FnMut(&T, &T) -> Ordering,
13+
F: FnMut(&T, &T) -> bool,
1414
{
1515
fn children_of(n: usize) -> (usize, usize) {
1616
(2 * n + 1, 2 * n + 2)
@@ -22,15 +22,14 @@ where
2222
return;
2323
}
2424

25-
let replacement_idx = if right_idx < heap.len()
26-
&& Ordering::Less == comparator(&heap[left_idx], &heap[right_idx])
27-
{
28-
right_idx
29-
} else {
30-
left_idx
31-
};
25+
let replacement_idx =
26+
if right_idx < heap.len() && is_less_than(&heap[left_idx], &heap[right_idx]) {
27+
right_idx
28+
} else {
29+
left_idx
30+
};
3231

33-
if Ordering::Less == comparator(&heap[origin], &heap[replacement_idx]) {
32+
if is_less_than(&heap[origin], &heap[replacement_idx]) {
3433
heap.swap(origin, replacement_idx);
3534
origin = replacement_idx;
3635
} else {
@@ -44,22 +43,24 @@ where
4443
}
4544
let mut storage: Vec<I::Item> = iter.by_ref().take(k).collect();
4645

46+
let mut is_less_than = move |a: &_, b: &_| comparator(a, b) == Ordering::Less;
47+
4748
// Rearrange the into a valid heap by reordering from the second-bottom-most layer up
4849
// Slightly faster than ordering on each insert, but only by a factor of lg(k)
4950
for i in (0..=(storage.len() / 2)).rev() {
50-
sift_down(&mut storage, &mut comparator, i);
51+
sift_down(&mut storage, &mut is_less_than, i);
5152
}
5253

5354
if k == storage.len() {
5455
// If we fill the storage, there may still be iterator elements left
5556
// So feed them into the heap
5657
// Also avoids unexpected behaviour with restartable iterators
5758
iter.for_each(|val| {
58-
if comparator(&val, &mut storage[0]) == Ordering::Less {
59+
if is_less_than(&val, &mut storage[0]) {
5960
// Treating this as an push-and-pop saves having to write a sift-up implementation
6061
// https://en.wikipedia.org/wiki/Binary_heap#Insert_then_extract
6162
storage[0] = val;
62-
sift_down(&mut storage, &mut comparator, 0);
63+
sift_down(&mut storage, &mut is_less_than, 0);
6364
}
6465
});
6566
}
@@ -72,7 +73,7 @@ where
7273
// Leaves the length shorter than the number of elements
7374
// so that sifting does not disturb already popped elements
7475
heap = &mut heap[..last_idx];
75-
sift_down(heap, &mut comparator, 0);
76+
sift_down(heap, &mut is_less_than, 0);
7677
}
7778

7879
storage

0 commit comments

Comments
 (0)