[算法 笔记]堆排序(续)
生活随笔
收集整理的這篇文章主要介紹了
[算法 笔记]堆排序(续)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上一篇有關堆排序的源碼是從STL標準庫中抽出來,但是源碼有點讓我混亂。最近閑來無事,再寫一篇有關堆排序的博客,并附上簡單的過程描述。
(參考書籍:《算法引論?——?一種創造性方法》?4.7和6.4.5節)
?
堆排序最壞情況下的運行時間是O(n?log?n)。堆排序中建堆方式有兩種:
1.?自頂向下建立大根堆。簡單點說,就是從無到有插入元素到堆中。這樣可以有效地維護了大根堆的性質,即大根堆是由滿足大根堆性質的子堆構成。
2.?自底向上建立大根堆。一般都是從堆存儲數組的一半的位置開始遞減比較。需要注意的是,在每次比較后,需要調整子堆來滿足大根堆的性質。有點類似于從建好的大根堆中移除元素之后的調整。(這種方式參考《數據結構(C語言版)》?嚴蔚敏,吳偉民著的10.4.3節)
通過上述資料會發現,自頂向下建立大根堆的方式要比自底向上建立大根堆的方式簡單。這里使用的是第一種方式:
1 void build_heap( int heap[], int current_size ) 2 { 3 int start = 0; 4 5 while ( start < current_size - 1 ) 6 { 7 // start在insert_to_heap函數會發生變化 8 insert_to_heap( heap, &start, start + 1, heap[start] ); 9 } 10 }在建立堆之后,堆排序的處理:只需要將大根堆中的最大值(heap[0])從堆中移除,并將其插入到數組的末尾(升序方式)。
?
1 void heap_sort( int heap[], int current_size ) 2 { 3 int i = current_size - 1; 4 int j = current_size; 5 6 build_heap( heap, current_size ); 7 while ( j ) 8 { 9 int data = remove_max_from_heap( heap, &j ); 10 heap[i] = data; 11 --i; 12 } 13 }?
完整的源碼:
1 #include <stdio.h> 2 #include <assert.h> 3 4 void swap_value( int heap[], int lhs, int rhs ) 5 { 6 int tmp = heap[lhs]; 7 heap[lhs] = heap[rhs]; 8 heap[rhs] = tmp; 9 } 10 11 /** @*current_size: 表示heap中已經存在的元素個數。 12 ** @heap_size:表示heap的最大容量是多少 13 */ 14 void insert_to_heap( int heap[], int *current_size, 15 int heap_size, const int value ) 16 { 17 int child = *current_size; 18 int parent = 0; 19 20 assert( *current_size < heap_size ); 21 heap[child++] = value; 22 parent = child / 2; 23 while ( parent >= 0 ) 24 { 25 if ( heap[child] > heap[parent] ) 26 { 27 swap_value( heap, child, parent ); 28 child = parent; 29 parent /= 2; 30 } 31 else 32 parent = -1; 33 } 34 *current_size += 1; 35 } 36 37 int remove_max_from_heap( int heap[], int *current_size ) 38 { 39 int result = 0; 40 int child = 0; 41 int parent = 0; 42 43 if ( *current_size == 0 ) 44 { 45 printf( "remove_max_from_heap: the heap is empty.\n" ); 46 return -1; 47 } 48 49 result = heap[0]; 50 swap_value( heap, 0, *current_size - 1 ); 51 --*current_size; 52 child = 1; 53 while ( child <= *current_size - 1 ) 54 { 55 if ( child < *current_size - 1 56 && heap[child] < heap[child + 1] ) 57 { 58 child += 1; 59 } 60 61 if ( heap[child] > heap[parent] ) 62 { 63 swap_value( heap, child, parent ); 64 parent = child; 65 child *= 2; 66 } 67 else 68 { 69 child = *current_size; 70 } 71 } 72 73 return result; 74 } 75 76 void build_heap( int heap[], int current_size ) 77 { 78 int start = 0; 79 80 while ( start < current_size - 1 ) 81 { 82 insert_to_heap( heap, &start, start + 1, heap[start] ); 83 } 84 } 85 86 void heap_sort( int heap[], int current_size ) 87 { 88 int i = current_size - 1; 89 int j = current_size; 90 91 build_heap( heap, current_size ); 92 while ( j ) 93 { 94 int data = remove_max_from_heap( heap, &j ); 95 heap[i] = data; 96 --i; 97 } 98 } 99 100 int main() 101 { 102 int heap[] = { 78, 58, 87, 62, 92, 332, 55, 40, 75, 146 }; 103 int heap_size = sizeof(heap) / sizeof(int); 104 int i = 0; 105 106 heap_sort( heap, heap_size ); 107 while ( i < heap_size ) 108 { 109 printf( "%d ", heap[i++] ); 110 } 111 112 113 return 0; 114 } View Code?
?
轉載于:https://www.cnblogs.com/life91/p/3393644.html
總結
以上是生活随笔為你收集整理的[算法 笔记]堆排序(续)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实验 6 数组1输出最大值和它所对应的下
- 下一篇: 构造函数和析构函数能否声明为虚函数?