堆排序算法使用二叉堆實現排序,樹上的每個節點對應數組中的一個元素。算法
第一步:使用MAX_HEAPIFY維護一個最大堆(全部孩子節點都必須小於或等於其父節點)。它的輸入爲一個數組A和一下標i,調用MAX_HEAPIFY時,假設節點i的左右子樹都是最大堆。數組
僞碼:ide
1 LEFT(i) 2 return 2i 3 4 RIGHT(i) 5 return 2i+1 6 7 MAX_HEAPIFY(A,i) 8 9 l = LEFT(i) 10 11 r = RIGHT(i) 12 13 if l <=A.heap-size and A[l] > A[i] 14 15 largest = l 16 17 else 18 19 largest = i 20 21 if r<= A.heap-size and A[r] > A[largest] 22 23 largest = r 24 25 if largest != i 26 27 exchange A[i] with A[largest] 28 29 MAX_HEAPIF(A,largest)
假設節點i的左子數和右子數都是最大堆。程序首先找出節點i,它的左孩子節點和右孩子節點中最大的一個,如節點i是最大,那麼以i爲根節點二叉堆就是最大堆了程序結束;不然,交換節點i和最大那個節點largest,因而以largest爲根節點的二叉樹就有可能違反了最大堆的性質,所以以largest爲下標遞歸調用MAX_HEAPIFY。spa
第二步:使用BUILD_MAX_HEAP(A)創建一個最大堆。code
僞碼:blog
1 BUILD-MAX_HEAP(A) 2 3 A.heap-size = A.length 4 5 for i = ⌊A.length / 2⌋ downto 1 6 7 MAX_HEAPIFY(A,i)
從底向上的方法利用MAX_HEAPIFY把長度爲n的數組A轉換爲一個最大堆。這裏咱們不用從數組A的最後一個元素開始調用MAX_HEAPIFY,能夠證實:從⌊n/2⌋ + 1 到n中的元素都是數的葉節點(沒有孩子節點),因此咱們從⌊n/2⌋到1調用MAX_HEAPIFY,轉換A成爲一個最大堆.排序
第三步:使用BUILD_MAX_HEAP 和 MAX_HEAPIFY完成堆排序算法HEAPSORT遞歸
僞碼:it
1 HEAPSORT(A) 2 3 BUILD-MAX-HEAP(A) 4 5 for i = A.length downto 2 6 7 exchange A[1] with A[i] 8 9 A.heap-size = A.heap-size - 1 10 11 MAX-HEAPIFY(A,1)
首先:利用BUILD_MAX_HEAP 把傳入的數組A轉換爲一個最大堆,在最大堆中,根節點爲全部節點中最大的;event
而後:交換二叉堆根節點A[1]和最後一個節點A[n],這時數組中的最大的值被交換到數組的最後;把最後一個節點從堆中去掉,利用MAX_HEAPIFY重新維護數組A[1],A[n -1]爲一個最大堆
最後:循環上面步驟,把依次最大的值放到數組末尾,直到堆的大小降到2
時間複雜度:HEAPSORT過程的時間複雜度是O(nlgn),每次調用BUILD_MAX_HEAP的時間複雜度是O(n),n-1次調用MAX_HEAPIFY,每次時間爲O(lgn);
C++代碼:
1 #define LEFT(i) (2 * (i + 1) - 1) 2 #define RIGHT(i) (2 * (i + 1)) 3 4 #define EXCHANGE(a,b) (a) = (a) + (b);\ 5 (b) = (a) - (b);\ 6 (a) = (a) - (b) 7 8 void MAX_HEAPIFY(int A[],int i,int heap_size) 9 { 10 int l = LEFT(i); 11 int r = RIGHT(i); 12 int largest = -1; 13 14 if(l <= heap_size && A[l] > A[i]) 15 { 16 largest = l; 17 } 18 else 19 { 20 largest = i; 21 } 22 23 if(r <= heap_size && A[r] > A[largest]) 24 { 25 largest = r; 26 } 27 28 if(largest != i) 29 { 30 EXCHANGE(A[i],A[largest]); 31 MAX_HEAPIFY(A,largest,heap_size); 32 } 33 } 34 35 void BUILD_MAX_HEAP(int A[],int heap_size) 36 { 37 for(int i = heap_size / 2;i >=0;--i) 38 { 39 MAX_HEAPIFY(A,i,heap_size); 40 } 41 } 42 43 //堆排序,T(n) = O(nlgn) 44 void HEAPSORT(int A[],int heap_size) 45 { 46 BUILD_MAX_HEAP(A,heap_size); 47 for(int i = heap_size;i > 0;--i) 48 { 49 EXCHANGE(A[heap_size],A[0]); 50 heap_size -= 1; 51 MAX_HEAPIFY(A,0,heap_size); 52 } 53 }