Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BinaryHeap: Simplify sift down #29811

Merged
merged 1 commit into from
Nov 13, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/libcollections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,29 +521,30 @@ impl<T: Ord> BinaryHeap<T> {

while hole.pos() > start {
let parent = (hole.pos() - 1) / 2;
if hole.removed() <= hole.get(parent) { break }
if hole.element() <= hole.get(parent) { break; }
hole.move_to(parent);
}
}
}

fn sift_down_range(&mut self, mut pos: usize, end: usize) {
let start = pos;
/// Take an element at `pos` and move it down the heap,
/// while its children are larger.
fn sift_down_range(&mut self, pos: usize, end: usize) {
unsafe {
let mut hole = Hole::new(&mut self.data, pos);
let mut child = 2 * pos + 1;
while child < end {
let right = child + 1;
// compare with the greater of the two children
if right < end && !(hole.get(child) > hole.get(right)) {
child = right;
}
// if we are already in order, stop.
if hole.element() >= hole.get(child) { break; }
hole.move_to(child);
child = 2 * hole.pos() + 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@_@ what did this do?!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It did in fact make sure elements ended up in the right spot. Since sift down didn't compare anything with the element it wanted to sift down, it could obviously not put the element in the right place.

So the code got there by sifting the element all the way down, and then back up to where it belongs.

I found this all out when implementing this algorithm using the indexing crate..


pos = hole.pos;
}
self.sift_up(start, pos);
}

fn sift_down(&mut self, pos: usize) {
Expand Down Expand Up @@ -605,7 +606,7 @@ impl<'a, T> Hole<'a, T> {

/// Return a reference to the element removed
#[inline(always)]
fn removed(&self) -> &T {
fn element(&self) -> &T {
self.elt.as_ref().unwrap()
}

Expand Down