无聊时总结总结算法之07堆排序
来源:互联网 发布:国家数据标准规范 编辑:程序博客网 时间:2024/05/16 17:01
堆排序
- 二叉堆的定义
二叉堆是完全二叉树或者是近似完全二叉树。
二叉堆满足二个特性:
1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。下图展示一个最小堆:
由于其它几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆
实现堆排序
实现堆排序需解决两个问题:
1. 如何将n 个待排序的数建成堆;
2. 输出堆顶元素后,怎样调整剩余n-1 个元素,使其成为一个新堆。
首先讨论第二个问题:输出堆顶元素后,对剩余n-1元素重新建成堆的调整过程。
调整小顶堆的方法:
1)设有m 个元素的堆,输出堆顶元素后,剩下m-1 个元素。将堆底元素送入堆顶((最后一个元素与堆顶进行交换),堆被破坏,其原因仅是根结点不满足堆的性质。
2)将根结点与左、右子树中较小元素的进行交换。
3)若与左子树交换:如果左子树堆被破坏,即左子树的根结点不满足堆的性质,则重复方法 (2).
4)若与右子树交换,如果右子树堆被破坏,即右子树的根结点不满足堆的性质。则重复方法 (2).
5)继续对不满足堆性质的子树进行上述交换操作,直到叶子结点,堆被建成。
再讨论对n 个元素初始建堆的过程。
建堆方法:对初始序列建堆的过程,就是一个反复进行筛选的过程。
1)n 个结点的完全二叉树,则最后一个结点是第个结点的子树。
2)筛选从第个结点为根的子树开始,该子树成为堆。
3)之后向前依次对各结点为根的子树进行筛选,使之成为堆,直到根结点。
/** * 已知H[s…m]除了H[s] 外均满足堆的定义 * 调整H[s],使其成为大顶堆.即将对第s个结点为根的子树筛选, * * @param H是待调整的堆数组 * @param s是待调整的数组元素的位置 * @param length是数组的长度 * */void HeapAdjust(int H[],int s, int length){ int tmp = H[s]; int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置) while (child < length) { if(child+1 <length && H[child]<H[child+1]) { // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点) ++child ; } if(H[s]<H[child]) { // 如果较大的子结点大于父结点 H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点 s = child; // 重新设置s ,即待调整的下一个结点的位置 child = 2*s+1; } else // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出 { break; } H[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上 } print(H,length);}/** * 初始堆进行调整 * 将H[0..length-1]建成堆 * 调整完之后第一个元素是序列的最小的元素 */void BuildingHeap(int H[], int length){ //最后一个有孩子的节点的位置 i= (length -1) / 2 for (int i = (length -1) / 2 ; i >= 0; --i) HeapAdjust(H,i,length);}/** * 堆排序算法 */void HeapSort(int H[],int length){ //初始堆 BuildingHeap(H, length); //从最后一个元素开始对序列进行调整 for (int i = length - 1; i > 0; --i) { //交换堆顶元素H[0]和堆中最后一个元素 int temp = H[i]; H[i] = H[0]; H[0] = temp; //每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整 HeapAdjust(H,0,i); }}int main(){ int H[10] = {3,1,5,7,2,4,9,6,10,8}; cout<<"初始值:"; print(H,10); HeapSort(H,10); //selectSort(a, 8); cout<<"结果:"; print(H,10);}
- 无聊时总结总结算法之07堆排序
- 无聊时总结总结算法之02排序(希尔 完结)
- 无聊时总结总结算法之03简单选择排序
- 无聊时总结总结算法之04冒泡排序
- 无聊时总结总结算法之05快速排序
- 无聊时总结总结算法之06归并排序
- 无聊时总结总结算法之08桶排序
- 排序算法总结之堆排序
- 排序算法总结之堆排序
- 无聊时总结总结算法之02排序(直接插入+希尔)
- 基础算法总结之堆排序算法
- 【朝花夕拾之排序算法总结】 快速排序,堆排序总结
- 算法总结:堆排序
- 堆排序算法总结!
- 堆排序算法 总结
- 堆排序算法总结
- 堆排序算法 总结
- 堆排序算法 总结
- Oracle、Mysql、SQLServer数据分页查询
- Database LeetCode Second Highest Salary
- 日本猥琐雨伞设计:裙底伞
- ML学习分享系列(2)_计算广告小窥[中]
- android:自定义HorizontalScrollView实现qq侧滑菜单 标签: HorizontalScrollView自定义viewqq侧滑菜单 2016
- 无聊时总结总结算法之07堆排序
- 简单的二叉树创建、遍历(V1.0)
- 在应用层通过spring特性解决数据库读写分离
- 线程
- tkinter示例:随意测试
- POJ1094 Sorting It All Out(拓扑排序)
- 设置listview的数据为空时的提示
- Java的的三元运算符
- 关于float和double类型数据的输入输出