堆排序
来源:互联网 发布:阿里云备案客服电话 编辑:程序博客网 时间:2024/06/16 09:09
堆的概念
通俗的说就是小顶堆本身的值小于或等于自己的任一个孩子节点(如果有孩子节点的话),这样看来,小顶堆中根节点的值是所有元素中最小的。大顶堆则刚好相反。
堆节点的访问
通常堆是通过一维数组来实现的。在数组起始位置为0的情形中:
- 父节点i的左子节点在位置(2*i+1);
- 父节点i的右子节点在位置(2*i+2);
- 子节点i的父节点在位置floor((i-1)/2);
以下为上图中的大顶堆在一维数组中的的存储情况。
堆排序基本思想
根据堆的定义可以知道k[0]就是所有元素中最大的一个,把它与k[n-1]交换,变成下表的形式:
现在k[n-1]是最大的,它的位置就已经定下来了,再将K[0…n-2]调整为新的堆,如下:
接着把k[0]与k[n-2]交换,再将K[0…n-3]调整为新的堆。
重复这样的操作,直到k[0]与k[1]交换,完成排序。
现在就有两个问题,
第一个就是怎么样将一个初始序列建成堆的形式。
第二个就是删除根节点后,怎么将剩下的元素调整为新的堆。
初建堆
假设有数组如下:
将5和8,4和6交换位置之后,调整3的位置。
最后调整1的位置
这样就完成了建造大顶堆的过程。
删除根节点
以上为删除根节点的示意图,再将根节点删除之后,需要把堆的最后一个节点升为新的根节点,然后再对根节点进行位置调整,调整步骤同前面讲的步骤一样。
这也为什么进行排序时要将第一个元素和最后一个元素交换位置,这正好符合删除根节点的过程,这样就不必再重新创建一个数组来依次保存删除的元素。
c++实现
template<typename Type>void max_heapify(vector<Type> & a, int start, int end) { int dad = start; int son = dad * 2 + 1; while (son < end) { if (son + 1 < end && a[son] < a[son + 1]) //先比较两个子节点的大小,选择较大的 { son++; } if (a[dad] > a[son]) //如果父节点大于较大的子节点,则不需要调整 { return; } else { //否则交换位置,再继续子节点与孙节点的比较 swap(a[dad], a[son]); dad = son; son = dad * 2 + 1; } }}template<typename Type>void heap_sort(vector<Type> & a, int n) { //初始化,i从最后一个非叶子节点开始 for (int i = n / 2 - 1; i >= 0; --i) {//建造大顶堆 max_heapify(a, i, n); } for (int i = n - 1; i > 0; --i) {//先将第一个元素和已经排好元素的前一位做交换(第一次交换时,和最后一个元素交换,交换完毕后,最后一位就是已排好的元素), //再重新调整(刚调整的元素之前的元素),直到排序完毕。 swap(a[0], a[i]); max_heapify(a, 0, i); }}
0 0
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- 为知笔记 firefox浏览器插件安装 (2016.09)
- R12客户表结构分析
- HTML5安全:CORS(跨域资源共享)简介。。。ie67 out。。。
- 160422 dump DCD from u-boot.imx
- google 响应式编程 agera 试用
- 堆排序
- robot framework-requests库安装问题解决
- 【小松教你手游开发】【unity实用技能】NGUI Depth探索
- JSONObject与JAVABEAN之间的转换
- 鲁迅关于改变的名人名言
- Compressed Sparse Column format(CSC)
- WAMP本地环境配置多站点虚拟目录教程(详细)
- java运行本地命令
- HTTP:Web基础