排序算法之堆排序
来源:互联网 发布:js 点击图片放大 编辑:程序博客网 时间:2024/06/11 22:15
注:此文需要对有序二叉堆、优先队列等知识有所了解,建议看完用有序二叉堆实现优先队列后再阅读此文
和优先队列的关系
因为优先队列本身已经提供了删除最小(或最大)元素的接口,最简单的做法是将待排序数组依次插入优先队列中,再依次删除最小元素。此种做法需额外的空间(优先队列),且时间复杂度较高(相当于插入排序,外循环用于便利所有待排序元素,内循环用于向优先队列insert元素)。
操作步骤
- 待排序的数组可看做一个无序二叉堆(节点从0开始),从最后一个父节点((N-1)/2)开始依次进行sink操作,将其变为有序二叉堆
- 设int j = N-1, 将顶部根节点a[0](此时根节点为最大元素)和元素a[j]交换(相当于将最大元素置于数组末尾),然后将新的a[0]进行sink()动作,sink完成后新的最大元素(次于开始时的根节点)会置于a[0]位置。
- j- -,依次进行上述动作,直至j = 1;
代码实现
public void sort(Comparable<T>[] a ){ int N = a.length; int i = (N - 1) / 2; //i初始指向最后一个父节点 while(i >= 0){ sink(i, N-1); i--; }//将数组变为堆有序 int j = N - 1;//j初始指向数组最后一个位置 while(j >= 1){ swap(0, j);//将根节点和最末节点交换,则最大元素会位于数组最末 sink(0, j);//新的根节点“下沉”到正确位置后(但不能超出j的范围,因为j已经排序过),新的最大节点(仅次于交换前的根节点)会位于根节点位置 j--;//对下一个j排序 }}//和[用有序二叉堆实现优先队列](http://blog.csdn.net/a854702872/article/details/77687288)中的sink动作相比,加入bounds参数,限制sink的范围private void sink(int m, int bounds){ int n = m * 2 + 1; if (n >= bounds) { break; } if (a[n] < a[n++]) { n++; } if (a[m] < a[n]) { swap(m, n); }}
阅读全文
0 0
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之 堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- 排序算法之堆排序
- OPC UA--第十四部分 PubSub 发布订阅
- 快速排序
- leetcode 31. Next Permutation
- LeetCode
- SylixOS热插拔驱动接口(三)
- 排序算法之堆排序
- 浏览器兼容性问题
- python request库安装
- 【初探】 归并排序
- 索引动态模板的创建,删除,是否存在
- NOIP模拟题 通讯 强连通分量缩点 最小树形图--朱刘算法
- live555 源码分析:RTSPServer
- 用Eclipse新建一个web项目没有自动生成web.xml
- 9.2机房欢乐赛 礼物 (状态压缩+期望dp)