Auto merge of #93765 - zhangyunhao116:heapsort, r=m-ou-se

Optimize heapsort

The new implementation is about 10% faster than the previous one(sorting random 1000 items).
This commit is contained in:
bors 2022-06-20 18:09:30 +00:00
commit 5750a6aa27

View File

@ -188,22 +188,25 @@ pub fn heapsort<T, F>(v: &mut [T], mut is_less: F)
// This binary heap respects the invariant `parent >= child`. // This binary heap respects the invariant `parent >= child`.
let mut sift_down = |v: &mut [T], mut node| { let mut sift_down = |v: &mut [T], mut node| {
loop { loop {
// Children of `node`: // Children of `node`.
let left = 2 * node + 1; let mut child = 2 * node + 1;
let right = 2 * node + 2; if child >= v.len() {
break;
}
// Choose the greater child. // Choose the greater child.
let greater = if child + 1 < v.len() && is_less(&v[child], &v[child + 1]) {
if right < v.len() && is_less(&v[left], &v[right]) { right } else { left }; child += 1;
}
// Stop if the invariant holds at `node`. // Stop if the invariant holds at `node`.
if greater >= v.len() || !is_less(&v[node], &v[greater]) { if !is_less(&v[node], &v[child]) {
break; break;
} }
// Swap `node` with the greater child, move one step down, and continue sifting. // Swap `node` with the greater child, move one step down, and continue sifting.
v.swap(node, greater); v.swap(node, child);
node = greater; node = child;
} }
}; };