zoukankan      html  css  js  c++  java
  • 堆排序

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

    有关完全二叉树的性质   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 }
    View Code

  • 相关阅读:
    老天待我不薄,又来这么一题POJ1753
    HDOJ4857【拓扑排序】
    二分匹配ZOJ3646
    poj3185//BFS随便切...
    poj2239 poj1274【二分匹配】
    每天一水poj1502【最短路】
    POJ1466/HDOJ1068 谈谈二分匹配的时间复杂度
    纯拓扑排序一搞poj2367
    poj1477(水)
    用动态链表high-poj 1528
  • 原文地址:https://www.cnblogs.com/joyeehe/p/7868526.html
Copyright © 2011-2022 走看看