• 堆排序的C实现


    这几天有点抵触情绪,看过了快速排序还有一些别的东西,但是一点都不想写有点复杂的代码0 0拖到了今天终于写了前几天就应该自己写一下的堆排序,完全用C语言写的,下面把代码贴一下。很多地方写得并不好,不过已经经过了测试,可以正确运行。

     1 /*堆排序*/
     2 void percolateDown(int* A, int i, int n)//下滤操作
     3 {
     4     while (i <= ((n - 1) - 1) / 2)
     5     {
     6         int rc = 2 * i + 2, lc = 2 * i + 1;
     7         if (rc < n)//如果右孩子存在
     8         {
     9             int j = ((A[rc] > A[i]) ? ((A[rc] > A[lc]) ? rc : lc) : ((A[lc] > A[i]) ? lc : i));
    10             if (i == j) break;
    11             swap(A[j], A[i]);
    12             i = j;
    13         }
    14         else if(lc < n)//仅有左孩子(只有最后一个内部节点可能会这种情况)
    15         {
    16             if (A[i] >= A[lc]) break;
    17             if (A[i] < A[lc])
    18             {
    19                 swap(A[i], A[lc]);
    20                 i = lc;
    21             }
    22         }
    23         else 
    24             break;
    25     }
    26 }
    27 void buildHeap(int* A, int n)//将数组就地建堆
    28 {
    29     for (int i = ((n - 1) - 1) / 2; (i >= 0) && (i < n); i--)//从最后一个内部节点的位置开始
    30         percolateDown(A, i, n);
    31 }
    32 int delMax(int* A,int n)//删除最大元素,调用者自行更改规模
    33 {
    34     int max = A[0];
    35     A[0] = A[n - 1];
    36     percolateDown(A, 0, n - 1);
    37     return max;
    38 }
    39 void heapSort(int* A, int n)//堆排序主算法
    40 {
    41     buildHeap(A, n);//就地建堆
    42     while(n > 0)
    43     {
    44         A[n - 1] = delMax(A, n);//等价于交换未排序序列的末元素与堆顶最大元素
    45         n--;
    46     }
    47 }

    建堆是最为关键的环节,可以说堆建好了才能开始进行排序。这里为了保持高效,建堆采用的是Floyd就地建堆算法,就是从原数组最后一个内部节点的位置进行下滤操作,当下滤到外部节点或x,x->lc,x->rc节点中最大的就是x节点时,下滤结束,继续进行下一个节点的下滤。每次交换元素后,新的堆顶并不是一个合格的堆顶,因此需要对堆顶继续进行下滤操作,不过注意到,只有堆顶一个节点是不合适的,所以重新建堆的操作复杂度不超过O(logn),即堆的高度。

    后面可能还会写一个K-选取的问题,即选取数组中第K大的元素,或者选取前K大的元素这种问题。基于优先级队列的方法,是一个可行的解,不过最坏情况的复杂度并不让人满意。

  • 相关阅读:
    人生中最重要的三位老师
    自我介绍
    秋季学习总结
    第五周学习总结
    第四周总结
    第三周基础作业
    判断上三角矩阵
    第二周作业及编程总结
    求最大值及其下标
    查找整数
  • 原文地址:https://www.cnblogs.com/lustar/p/7375661.html
Copyright © 2020-2023  润新知