此文章已於 19:56:03 2015/5/7 從新發布到 Feeeios
【算法導論】堆排序算法
堆排序的原理:數組
構建而且維持一個最大堆,而後交換堆的第一個和最後一個元素,每次交換後最大的元素都被移到最後。而後堆的規模減一,繼續交換,直到進行到第二個元素。這時排序完成ui
圖解:(圖片來源於http://blog.163.com/zhoumhan_0351/blog/static/399542272009918112712205/)spa
堆排序的過程:code
1, 維持最大堆,Max_heap過程用於維護最大堆的性質。blog
Max_heap(A,i)排序
L = 2 * i圖片
R = 2 * 1 + 1get
If L < size and A[L]>A[i]
Largest = l
Else
Largest = i
If R < size and A[R]>A[i]
Largest = R
If Largest != i
Exchange(A[i],A[Largest])
Max_heap(A,Largest)
2, 創建最大堆,該過程從size/2開始(之後的元素都沒有左右子樹),向上使用Max_heap,使整個對成爲一個最大堆
Build_heap(A)
For i = size / 2 to 1
Max_heap(A,i)
3, 堆排序
Heap_sort(A)
Build_heap(A)
For i = size to 2
Exchange(A[1],A[i])
size = size -1
Max_heap(A,1)
算法分析:
維持一個最大堆的複雜度爲Ɵ(lgN),創建一個最大堆的複雜度爲Ɵ(N),Heap_sort過程調用了一次Build_Heap, n-1次Max_Heap。總的複雜度爲Ɵ(N'l'g'N)
C++源代碼:
1 #include <iostream> 2 #include <algorithm> 3 4 using namespace std; 5 6 //維護堆的性質,使堆都能維持爲最大堆 7 void Max_Heap(int *a,int i,int size) 8 { 9 int l = 2 * i + 1; //獲得左孩子 ,因爲數組下標從0開始,因此左孩子爲2*i+1 10 int r = 2 * i + 2; //獲得右孩子 11 int max; 12 13 if(l <= size-1 && a[l] > a[i]){ 14 max = l; 15 } 16 else 17 max = i; 18 if(r <= size-1 && a[r] > a[max]){ 19 max = r; 20 } 21 if(max != i){ 22 swap(a[i],a[max]); 23 Max_Heap(a,max,size); 24 } 25 } 26 27 void HeapBUild(int *a,int size){ 28 int i; 29 for(i = size/2-1;i>=0;i--){ 30 Max_Heap(a,i,size); 31 } 32 } 33 34 void HeapSort(int *a,int size){ 35 int i; 36 HeapBUild(a,size); 37 for(i=size-1;i>0;i--){ 38 swap(a[0],a[i]); 39 Max_Heap(a,0,i); 40 } 41 } 42 43 int main(int argc,char *argv[]){ 44 int i; 45 int a[]={2,3,1,4,6,7,5}; 46 int size = 7; 47 HeapSort(a,size); 48 for(i = 0; i < size; i++) 49 cout<<a[i]<<" "; 50 return 0; 51 }