要想明白堆排序,首先要明白堆和数组是等价的本质,还要熟悉完全二叉树的性质。
有关完全二叉树的性质 http://www.cnblogs.com/joyeehe/p/7865578.html
最大堆排序源码:
注意:假设待排序数组是a[101],此程序,对索引1到101的单元排序,不处理a[0],因为我使用的是从1开始编号的完全二叉树。
给函数传参时,传的是实际处理的元素个数问不是数组的长度,即100。
子函数1 ----> 向下调整代码
void DownAdjust(int *a, int len, int i) { int max; while (i <= (len >> 1)) {//当结点有孩子时 max = (i << 1); if ((max + 1) <= len && a[(max + 1)] > a[max]) max = max + 1;//得到最大的孩子结点的索引 if (a[max] > a[i]) { swap(&a[max], &a[i]); i = max;//如果孩子大于父节点,就交换,被交换的孩子可能不再满足堆, }//要继续调整 else return;//不发生交换,说明已经达到平衡,结束 } }
i是待调整的结点。
此子函数的功能是:以结点 i 为根的树 的左子树和右子树都是堆,唯有结点 i 和它的左右孩子不满足堆,执行完此子函数,便能使以结点 i 为根的树是堆。
子函数2 ----> 建堆
1 void BuildHeap(int *a, int len) { 2 for (int j = (len >> 1); j >0; --j) { 3 DownAdjust(a, len, j); 4 } 5 }
从最后一个有孩子的结点开始调整,直到第一个结点,堆建好。
堆排序函数
1 void HeapSort(int *a, int len) { 2 if (a == null || len < 1) 3 return; 4 BuildHeap(a, len); 5 for (int k = len; k > 0; --k) { 6 swap(&a[1], &a[k]); 7 DownAdjust(a, k-1, 1); 8 } 9 }
能理解(排序过程就是每次挑个最大的数放在最后一个位置,就像冒泡排序)这句话,就算明白了堆排序函数。
完整源码和测试结果
1 #include"头文件.h" 2 /*堆排序*/ 3 void swap(int *a, int *b) { 4 int temp = *a; 5 *a = *b; 6 *b = temp; 7 } 8 /* 9 a是数组的基地址,len是数组的长度,i是待调整的结点 10 着重 11 */ 12 void DownAdjust(int *a, int len, int i) { 13 int max; 14 while (i <= (len >> 1)) {//当结点有孩子时 15 max = (i << 1); 16 if ((max + 1) <= len && a[(max + 1)] > a[max]) 17 max = max + 1;//得到最大的孩子结点的索引 18 if (a[max] > a[i]) { 19 swap(&a[max], &a[i]); 20 i = max;//如果孩子大于父节点,就交换,被交换的孩子可能不再满足堆, 21 }//要继续调整 22 else return;//不发生交换,说明已经达到平衡,结束 23 } 24 } 25 26 void BuildHeap(int *a, int len) { 27 for (int j = (len >> 1); j >0; --j) { 28 DownAdjust(a, len, j); 29 } 30 } 31 32 void HeapSort(int *a, int len) { 33 if (a == null || len < 1) 34 return; 35 BuildHeap(a, len); 36 for (int k = len; k > 0; --k) { 37 swap(&a[1], &a[k]); 38 DownAdjust(a, k-1, 1); 39 } 40 } 41 int main() { 42 int a[101]; 43 for (int i = 0; i < 101; ++i) { 44 a[i] = 1 + rand() % 10; 45 } 46 printf("排序前a[0] = %d ", a[0]); 47 printf("排序前的数组: "); 48 for (int i = 1; i < 101; ++i) { 49 printf("%4d ", a[i]); 50 if ((i + 1) % 10 == 0) 51 printf(" "); 52 } 53 printf(" "); 54 printf("排序后的数组: "); 55 HeapSort(a,100); 56 for (int i = 1; i < 101; ++i) { 57 printf("%4d ", a[i]); 58 if ((i+1) % 10 == 0) 59 printf(" "); 60 } 61 printf(" "); 62 printf("排序后a[0] = %d ", a[0]); 63 system("pause"); 64 return 0; 65 }