基本思想:
基本思想主要就是两点:构建初始化堆和排序。
以构建最大堆为例,可以分为以下几个步骤:
1、将初始待排序序列(A0,A1,A2....An-1)构建成最大堆,此堆为初始的无序堆。
2、将堆顶元素A0与最后一个元素Rn-1交换,此时得到一个新的无序序列(A0,A1,A2....An-2)和新的有序序列An-1,且满足A[0,2...n-2]<=A[n-1]。
3、由于交换后新的堆顶A0可能违反最大堆的性质,因此需要对当前无序区(A0,A1,A2....An-2)调整为新堆,然后再次将A[0]与无序区最后一个元素交换,得到新的无序区(A0,A1....An-3)和新的有序区(An-2,An-1)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
代码:
void HeapAdjust(int A[],int i,int size)//构造最大堆过程 { int lchild=2*i+1;//节点的左孩子编号 int rchild=2*i+2;//节点的右孩子编号 int max=i;//用来记录最大元素编号 if(i<=size/2-1) { if(lchild<=size-1 && A[lchild]>A[max])//左孩子比节点值要大 max=lchild; if(rchild<=size-1 && A[rchild]>A[max])//右孩子比节点值要大 max=rchild; if(max!=i)//若上面发生了交换 { swap(A[i],A[max]);//交换其对应的值 HeapAdjust(A,max,size);//判断是否还要向下调整 } } } void HeapSort(int A[],int n)//堆排序 { for(int i=(n-2)/2; i>=0; i--)//构造最大堆,非叶子节点从(n-2)/2开始 HeapAdjust(A,i,n); for(i=n-1; i>0; i--) { swap(A[0],A[i]);//堆顶和堆底元素交换位置 HeapAdjust(A,0,i);//每次从A[0]向下调整为堆 } }
设树深度为k,。从根到叶的筛选,元素比较次数至多2(k-1)次,交换记录至多k 次。所以,在建好堆后,排序过程中的筛选次数不超过下式:
而建堆时的比较次数不超过4n 次,因此堆排序最坏情况下,时间复杂度也为:O(nlogn )。
http://blog.csdn.net/puqutogether/article/details/43934953
http://blog.csdn.net/hguisu/article/details/7776068
原文地址:http://blog.csdn.net/happywq2009/article/details/45503571