堆排序
来源:互联网 发布:税控接口软件 编辑:程序博客网 时间:2024/06/07 13:29
堆排序
堆的概念
堆本身为一棵完全二叉树,即拥有的特点是n个结点的堆的高度为
堆分为大根堆和小根堆。
大根堆指所有结点的关键字不小于其子结点的关键字的完全二叉树。
小根堆指所有结点的关键字不大于其子节点的关键字的完全二叉树。
堆排序原理和过程
堆排序就是利用了大根堆和小根堆的其整棵树的根结点一定是整棵树的最大值或者最小值这个性质。
流程:
1、将带排序的序列构建成一个堆结构;
2、将第一个元素和最后一个元素交换,也就是将根结点的元素和堆中最后一个元素交换,将堆的长度减一;
3、重新对堆进行维护;
4、重复2和3直到堆的长度变为0截至。
堆排序中最关键的就是堆的维护工作,堆的维护就是利用递归不断比较根结点和子结点的元素大小,从底部向上将符合条件的元素上升到相应的根结点中。
如下如图为一个大根堆的建立过程:
上图可能不是很具有代表性,因为元素交换也可能造成结点和子结点之间的关系不符合堆的特性。下面有相关代码可以自己进行调试完整理解相关的算法执行过程。
排序示意图:
堆排序的效率
堆排序是不稳定的排序算法,最坏情况下的时间复杂度为
C语言代码
/*** 堆排序算法(L为要进行排序的线性顺序表)*/typedef int type;void print_array(type *L, int len, char *msg);/*** 用于交换元素*/void swap(type *a, type *b){ type tmp = *a; *a = *b; *b = tmp;}/*** L 为type类型的可进行大小对比的线性顺序表* len 为线性顺序表的长度*//** * 维护堆的结构,大根堆 */void max_heap(type *L, int i, int len){ int max = 0; //保存最大值的下标 int left = 2 * i + 1; //本应为2i但是因为数组的起点为0因此要移位 int right = 2 * i + 2; if (left < len && L[left] > L[i]) { max = left; } else { max = i; } if (right < len && L[right] > L[max]) { max = right; } if (i != max) { swap(&L[i], &L[max]); max_heap(L, max, len); }}/** * 构建堆,大根堆 */void build_heap(type *L, int len){ int i = 0; for (i = len / 2; i >= 0; i--) { max_heap(L, i, len); }}/** * 堆排序 */void heap_sort(type *L, int len){ int i = 0; build_heap(L, len); for (i = len - 1; i > 0; i--) { swap(&L[0], &L[i]); max_heap(L, 0, i); }}
0 0
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- Netty 源码分析之 EventLoop(一)
- DC 平衡双向控制串行器 转接口IC GM8913:LVTTL转FPD-LINK III芯片
- list集合排序问题
- Android中popupwindow弹出灰色背景遇到的坑
- WebRTC中RTP/RTCP协议实现分析【转】
- 堆排序
- WebLogic11g-部署web应用(以Springside3为例)
- Delphi 多层数据库无状态模式下 ClientDataSet 分段读取服务器端记录的方法
- Azure Active Directory 开发人员指南
- mysql通过某字段里的部分内容搜索(附TP中FIND_IN_SET的使用)
- 前端性能优化
- jquery的attr和prop
- view的onFinishInflate()何时调用的
- Activity的生命周期,BACK键和HOME键生命周期