堆排序

Posted 旗正飘飘 马正萧萧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆排序相关的知识,希望对你有一定的参考价值。

要想明白堆排序,首先要明白堆和数组是等价的本质,还要熟悉完全二叉树的性质。

有关完全二叉树的性质   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\\n", a[0]);
47     printf("排序前的数组:\\n");
48     for (int i = 1; i < 101; ++i) {
49         printf("%4d ", a[i]);
50         if ((i + 1) % 10 == 0)
51             printf("\\n");
52     }
53     printf("\\n");
54     printf("排序后的数组:\\n");
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("\\n");
60     }
61     printf("\\n");
62     printf("排序后a[0] = %d\\n", a[0]);
63     system("pause");
64     return 0;
65 }
View Code

以上是关于堆排序的主要内容,如果未能解决你的问题,请参考以下文章

选择排序(简单选择排序堆排序的算法思想及代码实现)

排序--08---堆排序

python代码实现堆排序

算法-java代码实现堆排序

一文带你了解堆排序

堆排序