堆排序是个不稳定的算法
堆排序的思路就是不断维护一个大根堆(或者小根堆),然后不断把堆顶元素拿出来(当然拿出来之后还需要维护),就可以得到一个有序序列。
1,根据所给序列建立一个大根堆。
2,从大根堆中拿出根元素(此时打破了堆的结构,需要对堆进行维护,即使得剩下的元素满足堆的要求)。
3,不断重复步骤2,直到所有的元素都已经被排序好。
#include<iostream> #include<cstdio> #include<cmath> using namespace std;//堆排序 #define RecType int void sift(RecType R[],int low,int high) { //调整堆的算法,逐级向下调整,直到编号为high的节点为止 int i=low, j=2*i; //R[j]是R[i]的左孩子 RecType tmp=R[i]; while (j<=high) { //这里维护一个大根堆 if (j<high && R[j]<R[j+1]) j++; if (tmp<R[j]) { //双亲小 R[i]=R[j]; //将R[j]调整到双亲结点位置 i=j; //修改i和j值,以便继续向下筛选 j=2*i; } else break; //双亲大:不再调整 } R[i]=tmp; return; } void HeapSort(RecType R[],int n) { int i; RecType temp; for (i=n/2; i>=1; i--) //循环建立初始堆//因为n/2之后的节点肯定是叶子结点 sift(R,i,n); for (i=n; i>1; i--) { //进行n-1次循环,每次将堆顶的元素(最大值)放到队列最后 temp=R[1]; //R[1] ? R[i] R[1]=R[i]; R[i]=temp; sift(R,1,i-1); //筛选R[1]结点,得到i-1个结点的堆 } } void disp(int R[],int n) { for(int i=1;i<=n;i++) printf("%d ",R[i]); printf("\n"); } int main() { RecType R[]={9,1,4,3,5,0,2,6,8,7}; int n=9; disp(R,n); HeapSort(R,n); disp(R,n); return 0; }