思路参考《算法导论》P84
堆排序中用到的最重要的就是堆这种数据结构,也正是因为这种数据结构能把时间复杂度控制在O(n * lgn)
heapsort算法主要依赖于两个函数
MAX_HEAPIFY(int *A,int i,int len)
用于维护最大堆,时间复杂度为O(lgn),注意书上描述这个函数的算法只用了两个形参,而由于C++无法通过指针获取数组的大小,所以我额外添加了一个参数作为数组的大小
BUILD_MAX_HEAP(int *A,int len)
从无序的输入数据数组中构造一个最大堆,时间复杂度为O(n),这里同样添加了一个参数
如果用其他语言比如Java实现,只需把数组名作为参数穿进来即可,Java支持数组拷贝,支持通过数组名获取数组大小,比这里简单一点
排序算法的详细过程就不描述了,书上讲的挺清楚的
----------------------------------------------------------代码-------------------------------------------------------
1 // Heapsort.cpp: 定义控制台应用程序的入口点。 2 // 3 4 5 #include "stdafx.h" 6 #include <iostream> 7 8 using namespace std; 9 10 int PARENT(int i) 11 { 12 return (i - 1) / 2; 13 } 14 15 int LEFT(int i) 16 { 17 return 2 * i + 1; 18 } 19 20 int RIGHT(int i) 21 { 22 return 2 * i + 2; 23 } 24 //维护最大堆,时间复杂度为O(lgn) 25 int MAX_HEAPIFY(int *A,int i,int len) 26 { 27 int l, r, largest;//l为左孩子的下标,r为右孩子的下标,largest为三者中最大数的下标 28 int temp; 29 l = LEFT(i); 30 r = RIGHT(i); 31 if (l < len && A[l] > A[i]) 32 largest = l; 33 else 34 largest = i; 35 36 if (r < len && A[r] > A[largest]) 37 largest = r; 38 39 if (largest != i) 40 { 41 temp = A[i]; 42 A[i] = A[largest]; 43 A[largest] = temp; 44 MAX_HEAPIFY(A, largest, len); 45 } 46 else 47 { 48 if (l >= len && r >= len)//到达了叶节点,停止递归 49 { 50 return 0; 51 } 52 MAX_HEAPIFY(A, l, len); 53 MAX_HEAPIFY(A, r, len); 54 } 55 } 56 57 //从无序的输入数据数组中构造一个最大堆,时间复杂度为O(n) 58 int BUILD_MAX_HEAP(int *A,int len) 59 { 60 int start = PARENT(len); 61 for (int i = start; i >= 0; i--) 62 { 63 MAX_HEAPIFY(A, i, len); 64 } 65 return 0; 66 } 67 68 int HEAPSORT(int *A,int len) 69 { 70 int length = len; 71 int *res = new int[len]{0};//记录排完序后的结果 72 int ptr = len - 1; 73 BUILD_MAX_HEAP(A, len); 74 75 for (int i = 0; i < length; i++) 76 cout << A[i] << ends; 77 cout << endl << endl; 78 79 for (int i = length; i >= 1; i--) 80 { 81 res[ptr--] = A[0]; 82 A[0] = A[len-1]; 83 len--; 84 int *A_temp = new int[len]; 85 for (int i = 0; i < len; i++)//把删掉最后一个元素后的数组A复制到A_temp中 86 { 87 A_temp[i] = A[i]; 88 } 89 MAX_HEAPIFY(A_temp, 0, len);//对A_temp重新维持为最大堆 90 for (int i = 0; i < len; i++)//把A_temp的值复制给A 91 { 92 A[i] = A_temp[i]; 93 } 94 95 for (int i = 0; i < len; i++) 96 cout << A[i] << ends; 97 cout << endl; 98 delete A_temp; 99 } 100 101 cout << "排序后的数组为(升序):" << endl; 102 for (int i = 0; i < length; i++) 103 cout << res[i] << ends; 104 cout << endl; 105 return 0; 106 } 107 108 int main() 109 { 110 int A[] = {16,4,10,14,7,9,3,2,8,1}; 111 cout << "排序前的数组为:" << endl; 112 for (auto c : A) 113 cout << c << ends; 114 cout << endl; 115 /*BUILD_MAX_HEAP(A,10); 116 for (auto c : A) 117 cout << c << ends; 118 cout << endl;*/ 119 HEAPSORT(A,10); 120 return 0; 121 }
运行结果: