本文讨论的排序为从小到大。
堆排序的思路:1. 建立最大堆(注意只是最大堆,各结点并没有严格遵守大小大小);2. 排序的过程实际是把堆顶元素与最后一个元素交换,然后把最后一个元素(交换后)移出堆(通过堆大小减一来控制),接着对堆顶元素进行堆化操作。
步骤详解:
- 建立最大堆:从最后一个非叶子结点开始向前,对每一个结点进行堆化。注意,对某节点堆化过程中,可能需要其子节点进行堆化。
- 排序过程:首先建立最大堆,然后从最后一个结点开始向前对每个结点(假设其索引为index)执行如下过程:把索引为index的元素与第一个元素交换,然后把最后一个元素移出堆(通过堆大小减一),并针对第一个元素进行堆化。
1 struct Heap { 2 int heapSize; //堆大小 3 int length; //堆容量 4 int *arr; 5 }; 6 7 void print(Heap heap); 8 void heap_sort(Heap heap); 9 void start_heap_sort();
1 #define PARENT(i) ((i-1)/2) 2 #define LEFT(i) (2*i+1) 3 #define RIGHT(i) (2*i+2) 4 5 void print(Heap heap) { 6 for (int i = 0; i < heap.length; ++i) { 7 std::cout << heap.arr[i] << '\t'; 8 } 9 cout << endl; 10 } 11 12 void max_heapify(Heap heap, int index) { 13 int left = LEFT(index); 14 int right = RIGHT(index); 15 int largest; 16 if (left < heap.heapSize && heap.arr[left] > heap.arr[index]) 17 largest = left; 18 else 19 largest = index; 20 if (right < heap.heapSize && heap.arr[right] > heap.arr[largest]) 21 largest = right; 22 23 if (largest != index) { 24 swap(heap.arr, largest, index); 25 max_heapify(heap, largest); 26 } 27 } 28 29 void build_max_heap(Heap heap) { 30 heap.heapSize = heap.length; 31 for (int index = heap.length/2 - 1; index >= 0; --index) { 32 max_heapify(heap, index); 33 cout << "第" << index << "趟建堆" << endl; 34 print(heap); 35 } 36 } 37 38 void heap_sort(Heap heap) { 39 build_max_heap(heap); 40 cout << "After build:" << endl; 41 print(heap); 42 for (int index = heap.length-1; index > 0; --index) { 43 swap(heap.arr, index, 0); 44 heap.heapSize -= 1; 45 max_heapify(heap, 0); 46 } 47 } 48 49 void start_heap_sort() { 50 std::cout << "Sort start!" << std::endl; 51 int arr[] = {9, 2, 8, 5, 4, 7, 1, 6}; 52 Heap heap; 53 heap.arr = arr; 54 heap.length = sizeof(arr) / sizeof(*arr); 55 heap.heapSize = heap.length; 56 57 std::cout << "Before sort:" << std::endl; 58 print(heap); 59 heap_sort(heap); 60 std::cout << "After sort:" << std::endl; 61 print(heap); 62 }