堆排序
堆排序基本概念
堆是一种数据结构,它是将一些数据放在物理数据结构:数组或者vector中;逻辑数据结构是完全二叉树。
如果根节点的值大于两个子节点值,就是大根堆;
如果根节点的值小于两个子节点值,就是小根堆。
用堆这种数据结构来实现排序,就是堆排序。
该算法的操作主要有
minheapify:最小堆处理,复杂度是O(logN)
find_min:找到最小值,复杂度是O(1)
delete_min:删除最小值节点,及根节点,复杂度是O(logN)
build_minheap:建立最小堆,复杂度是O(N)
minheap_sort:最小堆排序,复杂度是O(NlogN)
算法导论中该算法在minheapify时用的是递归,如下程序用的是迭代处理,效率会更高一些;
如下程序实现的是小根堆
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include<iostream> #include<cstdio> #include<stdlib.h> #include<assert.h> #include<map> #include<vector> using namespace std; void minheapify(vector< double >& minheap, int pos){ while (1) { double temp=minheap[pos]; int loc=pos; if ((pos*2 <= minheap.size()-1) && minheap[pos]>minheap[pos*2]){ loc=pos*2; temp=minheap[pos*2]; } if ((pos*2+1 <= minheap.size()-1) && temp>minheap[pos*2+1]){ loc=pos*2+1; temp=minheap[pos*2+1]; } if (loc!=pos){ minheap[loc]=minheap[pos]; minheap[pos]=temp; pos=loc; continue ; } else if (loc==pos) break ; } } void build_minheap(vector< double >& minheap, double * a, int n){ for ( int i=0;i<n;i++) minheap.push_back(a[i]); for ( int i=(minheap.size()-1)/2;i>=1;i--) minheapify(minheap,i); } double find_min(vector< double >& minheap){ return minheap[1]; } void delete_min(vector< double >& minheap){ minheap[1]=minheap[minheap.size()-1]; minheap.erase(minheap.end()-1); minheapify(minheap,1); } vector< double > minheap_sort(vector< double >& minheap){ vector< double > result; while (minheap.size()>1){ result.push_back(find_min(minheap)); delete_min(minheap); } return result; } int main() { vector< double > minheap; minheap.push_back(-1); int n=5; double a[5]={100.1,20,3,5,2}; build_minheap(minheap,a,n); for ( int i=0;i<minheap.size();i++) cout<<minheap[i]<< " " ; cout<<endl<< "build complete" <<endl; vector< double > result; result=minheap_sort(minheap); for ( int i=0;i<result.size();i++) cout<<result[i]<< " " ; getchar (); return 0; } |