/*堆排序从数组的1开始,包含0的话没法计算儿子节点的位置*/ //调整大顶堆 void MAX_HEAPIFY(int a[],size_t la,size_t i) { size_t lagest,l,r;//lagest存放最大元素的下标,l存放i的左孩子下标,r存放i的右孩子下标 l=2*i; r=2*i+1;//由于堆是一个完全二叉树的结构,则i的孩子如果存在,下标必为2i和2i+1,i的父节点必为(i/2)向下取整 int temp;//用作交换时的临时空间 /*寻找i及其子节点中最大的一个*/ if (l<=la&&a[l]>a[i]) lagest=l; else//l>la,则说明没有左儿子,则i必是最大;若a[l]<a[i],同样i最大 lagest=i; if(r<=la&&a[r]>a[lagest]) lagest=r; if (lagest!=i)//说明需要交换 { temp=a[i]; a[i]=a[lagest]; a[lagest]=temp;//此时a[i]的值已经存入了a[lagest]中 MAX_HEAPIFY(a,la,lagest); } } //构建大顶堆 void BUILD_MAX_HEAP(int a[],size_t la) { //二叉树性质:n0=n2+1,因为堆是完全二叉树,则n1=0或者1,由n=n0+n1+n2,最终得到n0=(n+1)/2或者n/2 //构建大顶堆,从最后一个非叶子节点开始调整 for (size_t i=la/2;i>0;--i) MAX_HEAPIFY(a,la,i); } //堆排序 void HEAPSORT(int a[],size_t la) { //原理,大顶堆的第一个节点总是最大的元素,将它交换到最后,对剩下的元素调整成堆,获得第二大元素 int temp; size_t templa=la; BUILD_MAX_HEAP(a,la); for(size_t i=la;i>0;--i) { temp=a[i]; a[i]=a[1]; a[1]=temp; templa=templa-1; MAX_HEAPIFY(a,templa,1); } }