堆是是具有以下性质的完全二叉树:每个结点都大于或等于它的左右结点(大顶堆),或者每个结点都小于或等于它的左右结点(小顶堆),左右结点之间没有要求。
该算法的主要思想是:
1.假设现在已有一个大顶堆(调用buildheap()函数完成创建)。
2那么它的根结点肯定是最大的,现在将根结点与最后一个结点交换位置,使得最大值放到了最后,较小值放在了最前,放到最后表示这个数已排序完成,只需要排序它前面的数,即将数组长度减一。
3.因为最前有个较小数,所以需要重新用剩下的数组构成一个大顶堆(同样是调用buildheap())。
4.重复2,3步骤,直到数组中所有数字排序完成。
buildheap()函数:
传入一个结点,然后与它左右子树中最大的子树比较,若它大,满足堆性质,退出函数,若子树大,将子树放到它的位置,它的位置移动到子树位置,继续比较,直到子树比它小,退出函数。
#include"iostream" #include"time.h" using namespace std; void show(int *a,int n){ for(int i = 0;i < n;i++){ cout<<a[i]<<ends; } cout<<endl; } void buildheap(int *a,int s,int n){ int temp = a[s]; for(int i = 2 * s + 1;i < n;i = i * 2 + 1){ if(i < n - 1 && a[i] < a[i + 1]){ i++; } if(temp < a[i]){ a[s] = a[i]; s = i; } else{ break; } } a[s] = temp; } //堆排序 void heapsort(int *a,int n){ for(int i = n / 2;i >= 0;i--){ buildheap(a,i,n); } for(i = n - 1;i >= 0;i--){ int temp = a[i]; a[i] = a[0]; a[0] = temp; buildheap(a,0,i); } } int main(){ const int N = 10; int a[N]; srand(time(NULL)); for(int i = 0;i < N;i++){ a[i] = rand() % 10; } show(a,N); heapsort(a,N); show(a,N); return 0; }