首先是造轮子:
// maximum heap based on integer type
#include <bits/stdc++.h>
using namespace std;
const int MAX_SIZE = 100000;
int heap[MAX_SIZE], result[MAX_SIZE];
int size;
void init(){
memset(heap, 0, sizeof(heap));
memset(result, 0, sizeof(result));
}
bool is_leaf(int pos){
return pos > size / 2 - 1; // n/2 - 1 has been proved to be the last branch node in the tree
}
void swap(int a, int b){
int temp = heap[a];
heap[a] = heap[b];
heap[b] = temp;
}
bool is_legal(int pos){
return pos <= size - 1;
}
void sift_down(int pos){
int left, right;
while(!is_leaf(pos)){
left = 2 * pos + 1;
right = 2 * pos + 2;
if(is_legal(right)){ // node have both left child and right child
if(heap[pos] < max(heap[left], heap[right])){
if(heap[left] == max(heap[left], heap[right])){
swap(pos, left);
pos = left;
}
else{
swap(pos, right);
pos = right;
}
}
else{
break;
}
}
else if(is_legal(left)){ // node just have left child
if(heap[pos] < heap[left]){
swap(pos, left);
pos = left;
}
else{
break;
}
}
else{ // node have no left child or right child
break;
}
}
}
void build_heap(int *arr){
for(int i = 0 ; i < size ; i++){
heap[i] = arr[i];
}
for(int i = size / 2 - 1 ; i >= 0 ; i--){
sift_down(i);
}
}
//when there is just one num in the heap, then for sift_down function, 1 / 2 - 1 = -1;
int removefirst(){
int temp = heap[0];
swap(0, size - 1);
size--;
sift_down(0);
return temp;
}
void heap_sort(int* arr){
build_heap(arr);
for(int i = size - 1 ; i >= 0 ; i--)
result[i] = removefirst();
}
int main(){
cout << "Enter the size of the list: ";
cin >> size; // the size of the heap
int max_size = size;
init();
int *a = new int[size];
cout << "Enter n numbers: ";
for(int i = 0 ; i < max_size ; i++){
cin >> a[i];
}
heap_sort(a);
for(int i = 0 ; i < max_size ; i++){
cout << result[i] << " ";
}
return 0;
}
吐槽下,shaffer那本书真的有毒,就用来学习下思想,各种边界情况是不会有限制的
但个人挺喜欢里面的函数设计,命名和使用非常清晰易懂
然后是STL实现:
预备知识:STL里面的priority_queue
#include <bits/stdc++.h>
using namespace std;
struct Fish {
string color;
int weight;
Fish() {}
Fish(string c, int w) {color = c; weight = w;}
bool operator < (const Fish & f) const {
return weight > f.weight;
}
};
//Here, we define the fish with lower weight has supreme privilage
int main(){
priority_queue <Fish> q;
Fish f1("red", 100);
Fish f2("pink", 140);
Fish f3("blue", 99);
q.push(f1);
q.push(f2);
q.push(f3);
Fish temp;
while(!q.empty()){
temp = q.top();
q.pop();
cout << temp.color << " : " << temp.weight << endl;
}
return 0;
}
运行结果:
然后借助这个STL容器的重载可以实现堆排序
#include<bits/stdc++.h>
using namespace std;
int main(){
priority_queue <int> q;
int a[10] = {1,3,4,5,6,7,8,9,20,2};
for(int i = 0 ; i < 10 ; i++){
q.push(a[i]);
}
int temp = 0;
while(!q.empty()){
temp = q.top();
cout << temp << " ";
q.pop();
}
return 0;
}
运行结果:
当然,如果不想使用默认的值大的优先,可以重载如下:
#include<bits/stdc++.h>
using namespace std;
struct Num{
int num;
Num(){};
Num(int n){
num = n;
}
bool operator < (const Num & another) const{
return num > another.num;
}
};
int main(){
priority_queue <Num> q;
int a[10] = {1,3,4,5,6,7,8,9,20,2};
for(int i = 0 ; i < 10 ; i++){
q.push(Num(a[i]));
}
Num temp;
while(!q.empty()){
temp = q.top();
cout << temp.num << " ";
q.pop();
}
return 0;
}
输出结果: