排序算法----堆排序

堆排序算法使用二叉堆實現排序,樹上的每個節點對應數組中的一個元素。算法

第一步:使用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)
View Code

 假設節點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) 
View Code

從底向上的方法利用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)
View Code

 首先:利用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 }
View Code
相關文章
相關標籤/搜索