Skip to content

Commit

Permalink
Added heap sort.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwasham committed Jul 10, 2016
1 parent a5c7bcf commit 463382c
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 9 deletions.
13 changes: 12 additions & 1 deletion priority_queue/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ int main(int argc, char* argv[]) {
assert(max->key_ == 9827);
assert(max->value_ == "world");

//queue.PrintDebug();
// queue.PrintDebug();

jw::PQElement* max_element = queue.ExtractMax();
assert(max_element->key_ == 9827);
Expand All @@ -43,5 +43,16 @@ int main(int argc, char* argv[]) {

delete max_element;

// now we'll sort an array in-place

int to_sort[10] = {613, 55, 8721, 472, 94, 72, 74, 8, 61, 356};
int sorted[10] = {8, 55, 61, 72, 74, 94, 356, 472, 613, 8721};

jw::heapify(to_sort, 10);
jw::heap_sort(to_sort, 10);

assert(
std::equal(std::begin(to_sort), std::end(to_sort), std::begin(sorted)));

exit(EXIT_SUCCESS);
}
61 changes: 56 additions & 5 deletions priority_queue/priority_queue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int PriorityQueue::GetSize() { return size_; }

bool PriorityQueue::IsEmpty() { return size_ == 0; }

PQElement *PriorityQueue::ExtractMax() {
PQElement* PriorityQueue::ExtractMax() {
assert(size_ > 0);

PQElement* max = new PQElement;
Expand All @@ -80,17 +80,17 @@ PQElement *PriorityQueue::ExtractMax() {

void PriorityQueue::SiftDown(int index) {
while (index * 2 + 1 < size_) {

int left_child_index = index * 2 + 1;
int right_child_index = index * 2 + 2;
bool has_left_child = left_child_index < size_;
bool has_right_child = right_child_index < size_;
int swap_index = index;

if (has_left_child && has_right_child) {
if (elements_[left_child_index].key_ > elements_[right_child_index].key_) {
if (elements_[left_child_index].key_ >
elements_[right_child_index].key_) {
swap_index = left_child_index;
} else { // greater or equal to right child
} else { // greater or equal to right child
swap_index = right_child_index;
}
} else if (has_left_child) {
Expand All @@ -112,12 +112,63 @@ void PriorityQueue::SiftDown(int index) {
}

void PriorityQueue::Remove(int index) {
assert(index >=0 && index < size_);
assert(index >= 0 && index < size_);

Swap(index, size_ - 1);
--size_;

SiftDown(index);
}

void heapify(int* numbers, int count) {
for (int i = count / 2 - 1; i >= 0; --i) {
percolate_down(numbers, count, i);
}
}

void heap_sort(int* numbers, int count) {
int temp;
for (int i = count - 1; i > 0; --i) {
temp = numbers[i];
numbers[i] = numbers[0];
numbers[0] = temp;

percolate_down(numbers, i, 0);
}
}

void percolate_down(int* numbers, int count, int index) {
while (index * 2 + 1 < count) {
int swap_index = index;
int left_child_index = index * 2 + 1;
int right_child_index = index * 2 + 2;
bool has_left_child = left_child_index < count;
bool has_right_child = right_child_index < count;

if (has_left_child && has_right_child) {
if (numbers[left_child_index] > numbers[right_child_index]) {
swap_index = left_child_index;
} else {
swap_index = right_child_index;
}
} else if (has_left_child) {
swap_index = left_child_index;
} else if (has_right_child) {
swap_index = right_child_index;
} else {
break;
}

if (numbers[swap_index] > numbers[index]) {
int temp = numbers[index];
numbers[index] = numbers[swap_index];
numbers[swap_index] = temp;

index = swap_index;
} else {
break;
}
}
}

} // namespace jw
13 changes: 10 additions & 3 deletions priority_queue/priority_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class PriorityQueue {
bool IsEmpty();
// Returns the maximum key and value associated with it, removing it from the
// queue
PQElement* ExtractMax();
PQElement *ExtractMax();
// Remove the node with the given index
void Remove(int index);

Expand All @@ -43,11 +43,18 @@ class PriorityQueue {
void SiftUp(int index);
// Swaps 2 queue elements with the given indices
void Swap(const int index1, const int index2);
// Propagates the given node index down the tree until the subtree's heap property
// is satisfied
// Propagates the given node index down the tree until the subtree's heap
// property is satisfied
void SiftDown(int index);
};

// Turns an array into a heap
void heapify(int *numbers, int count);
// Sorts the given heapified array
void heap_sort(int *numbers, int count);
// Similar to SiftDown, but works on array of integers
void percolate_down(int *numbers, int count, int index);

} // namespace jw

#endif // PROJECT_PRIORITY_QUEUE_H

0 comments on commit 463382c

Please sign in to comment.