堆排序
不仅在排序上有较好的时间复杂度,同时最大堆,最小堆在解决top10等问题上有很好的效果。
最大堆性质,除了根以为的所有结点i都要满足:
A[parent(i)]>=A[i]
即,子节点一定小于等于父节点,且任意子树也满足该性质。
Max-Heapify是维持最大堆性质的关键。时间复杂度O(lgn).
#define LEFT(a) ((a)*2+1) #define RIGHT(a) ((a)*2+2) void ExChange(int& a,int& b) { a=a^b; b=a^b; a=a^b; } void Max_Heapify(int* intArr,int i,int length) { int l = LEFT(i); int r = RIGHT(i); int largest = i; if (l< length && intArr[l] >intArr[largest]) { largest = l; } if (r< length && intArr[r] >intArr[largest]) { largest = r; } if(largest!=i) { ExChange(intArr[i],intArr[largest]); Max_Heapify(intArr,largest,length); } }
通过Max_Heapify可以使root不符合性质递归保持最大堆的性质。
如下:
16
4 10
14 7 9 3
2 8 1
(a)
16
14 10
4 7 9 3
2 8 1
(b)
16
14 10
8 7 9 3
2 4 1
(c)
建堆:
通过自底向上的方法调用Max_Heapify,即可把一个数组转换为最大堆。
void Build_Max_Heap(int* intArr,int length) { for(int i=length/2+1;i>=0;i--) { Max_Heapify(intArr, i,length); } }
排序:
在有了一个最大堆后,通过不断取出最大值,并对剩余的值进行Max_Heapify即可保持最大堆性质,始终从根节点取得当前最大值,从而实现排序。
代码如下:
void Heap_Sort(int* intArr,int length) { Build_Max_Heap(intArr,length); for(int i= length-1;i>0;i--) { ExChange(intArr[0],intArr[i]); Max_Heapify(intArr,0,--length); } }
因为每次Max_Heapify时间为O(logn),所以堆排序时间为O(nlogn)
原文:http://www.cnblogs.com/stratrail/p/5040472.html