八大排序算法(4) 堆排序
来源:互联网 发布:电脑应用无法链接网络 编辑:程序博客网 时间:2024/05/04 20:21
基本思想
是对简单选择排序的改进,是一种树形结构的排序。
利用堆的特性,快速选择出序列中的最大最小元素。
堆的定义:
用树表示更加直观:
即:父节点 不大于/不小于 其子节点的完全二叉树。
降序时称为 大堆顶,升序时称为 小堆顶。
这样的堆,其堆顶就是整个序列中最大/最小的元素。
不断的取出堆顶、将剩下序列重组成堆的过程就叫堆排序。
树采用顺序存储:{96,83,27,38,11,09}, {12,36,24,85,47,30,53,91}
序列是树的顺序存储,因此 节点、父、子 在序列中的位置为 i,2i,2i+1, 反映到序列中的 index 为 i - 1, 2*i-1, 2*i。
重点
1. 初始化时将整个序列转换成堆 2. 取出堆顶后,将剩下的元素快速组成堆
先说第二点的算法思路:
1. 取出堆顶后 i 后,将堆底元素取出补为堆顶 2. 检查到堆被破坏,将 堆顶 与其子节点中小的元素交换 3. 对交换后的子树重复2
示例图:
再说第一点的算法思路:
1. 假设 长度 n 的 序列 k 为堆 2. 最后一个节点是 节点 n/2 的子节点,那么从 n/2 开始向上筛选 3. 从 父子节点 中选举最小的为 父节点 4. 对交换后的子节点 重复 3,直到叶子节点 5. 检查下一个 n/2 - 1 ,重复 3, 直到 0
示例图:
代码:
void printList(int *l, int n) { for (int i = 0; i < n; i++) { printf("%d ", l[i]); } printf("\n");}/* * 修复堆 * * 从 父子 节点中选举最小的为父节点。 * 如果最小的不是父节点的话,那么交换过的子节点也需要检查。 */void adjustHeap(int *l, int n, int topIndex, int adjustIndex) { // 要检查的元素 index int minIndex = adjustIndex; // 堆顶不为 0 时,计算 adjustIndex 的子节点 index 要考虑到偏移 int lcIndex = 2 * (adjustIndex - topIndex + 1) - 1 + topIndex; int rcIndex = 2 * (adjustIndex - topIndex + 1) + topIndex; // 跟 左子节点比较,替换 小的 index if (lcIndex < n && l[minIndex] > l[lcIndex] ){ minIndex = lcIndex; } // 跟 右子节点比较,替换 小的 index if (rcIndex < n && l[minIndex] > l[rcIndex]){ minIndex = rcIndex; } // 如果小的index 不是 堆顶的话,那么换顶,然后检查子堆 if ( minIndex != adjustIndex ){ int k = l[minIndex]; l[minIndex] = l[adjustIndex]; l[adjustIndex] = k; // 子堆 minIndex 换了 堆顶,要检查一下 adjustHeap(l, n, topIndex, minIndex); }}/* * 创建堆 * * 1、假设 长度 n 的 序列 k 为堆 * 2、最后一个节点为 n / 2 的子节点,从 n / 2 开始向上筛选 * 3、从 父子节点中选举最小的为 父节点 * 4、检查下一个 n / 2 - 1 ,重复 3, 直到 0 */void buildHeap(int *l, int n) { for (int i = n / 2; i > 0;i-- ) { // 节点 i 对应的 index 是 i - 1, 子节点 index 2 * i - 1、 2 * i int min = i - 1; int lc = 2 * i - 1; int rc = 2 * i; // 选举最小的为 堆顶 if (l[i - 1] > l[lc]){ min = lc; } if ( 2*i < n && l[min] > l[rc]){ min = rc; } if ( min != i-1 ) { int k = l[i - 1]; l[i - 1] = l[min]; l[min] = k; // 子堆 min 换了堆顶,要检查堆 min adjustHeap(l, n, 0, min); } }}int main() { int list[50] = { 10, 7, 1 , 8, 5, 12, 6, 3, 9 }; int n = 9; printList(list, n); // 创建小堆顶 buildHeap(list, n); printList(list, n); printf("======\n"); // 建好堆后,初始堆顶就是最小的 for (int i = n - 1; i > 0; i--) { //将堆顶换到堆底. 这是小堆顶,每次都将最小的元素换到堆底,然后 堆缩小 1,最后得出降序 int exchange = list[0]; list[0] = list[i]; list[i] = exchange; // 堆 0 被破坏,执行检查 adjustHeap(list, i, 0, 0); printList(list, n); } system("pause"); return 0;}
以上
原文链接 http://blog.csdn.net/u011546766/article/details/74045324
阅读全文
0 0
- 八大排序算法(4) 堆排序
- 八大排序算法(四)堆排序
- 八大排序算法-堆排序
- 八大排序算法--堆排序
- 八大排序算法-堆排序
- 八大排序算法 之 堆排序(二叉树排序)
- 八大排序算法之堆排序
- 八大排序算法之堆排序解析
- 八大排序算法——堆排序
- 八大排序算法之堆排序
- 八大排序--堆排序
- 八大种必知排序算法(三) 归并排序算法、堆排序算法详解 (续)
- 八大种必知排序算法(三) 归并排序算法、堆排序算法详解
- 【排序】用Python实现八大排序算法--堆排序
- 八大排序算法总结之二(简单选择算法,堆排序,归并排序,基数排序)
- 八大排序算法总结之二(简单选择算法,堆排序,归并排序,基数排序)
- 精通八大排序算法系列:二、堆排序算法
- 精通八大排序算法系列:二、堆排序算法
- jsp标签的用法
- session的一些常用方法
- 2017.07.01 上午咨询总结
- 【React Native】React Native之Could not get BatchedBridge,make sure...的问题
- 文章标题
- 八大排序算法(4) 堆排序
- poj 1149网络流建模(转载自Edelweiss代码自己编的有点丑陋0 0)
- 40亿个非负整数中找到没出现的数
- 网络征信服务
- 解压版的Tomcat注册成 Windows操作系统服务
- BZOJ 1227 DP+树状数组 解题报告
- 初识Activiti流程设计工具
- Spring IOC的配置使用(转)
- 安装keras库/tensorflow库出现的问题