排序知識點小結1-手寫堆排序及STL實現
阿新 • • 發佈:2018-12-11
首先是造輪子:
// 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;
}
輸出結果: