堆排序及代码实现

Posted luStar

tags:

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

这几天有点抵触情绪,看过了快速排序还有一些别的东西,但是一点都不想写有点复杂的代码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大的元素这种问题。基于优先级队列的方法,是一个可行的解,不过最坏情况的复杂度并不让人满意。

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

排序:Java实现大顶堆和二叉树的广度优先遍历原理及代码注释详解

算法-java代码实现堆排序

Java排序算法 - 堆排序的代码

堆排序算法的实现

数据结构图解七大排序

堆排序及手写堆的基本操作java代码