堆排序
来源:互联网 发布:tomcat修改1099端口 编辑:程序博客网 时间:2024/06/05 19:06
概念:堆是一棵顺序存储的完全二叉树。
小根堆:其中每个结点的关键字都不大于其孩子结点的关键字。
大根堆:其中每个结点的关键字都不小于其孩子结点的关键字。
对于数组:{R0, R1, ... , Rn}来说,Ri为根节点,R(2i+1)为左子节点,R(2i+2)为右子节点
(1) Ri <= R(2i+1) 且 Ri <= R(2i+2) (小根堆),即每个节点的值都不小于其父节点的值;
(2) Ri >= R(2i+1) 且 Ri >= R(2i+2) (大根堆),即每个节点的值都不大于其父节点的值;
堆排序思想:
(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大,大根堆)。
(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。
时间复杂度:排序过程的时间复杂度是O(nlgn)。因为建堆的时间复杂度是O(n)(调用一次);调整堆的时间复杂度是lgn,调用了n-1次,所以堆排序的时间复杂度是O(nlgn)[2]
小根堆:其中每个结点的关键字都不大于其孩子结点的关键字。
大根堆:其中每个结点的关键字都不小于其孩子结点的关键字。
对于数组:{R0, R1, ... , Rn}来说,Ri为根节点,R(2i+1)为左子节点,R(2i+2)为右子节点
(1) Ri <= R(2i+1) 且 Ri <= R(2i+2) (小根堆),即每个节点的值都不小于其父节点的值;
(2) Ri >= R(2i+1) 且 Ri >= R(2i+2) (大根堆),即每个节点的值都不大于其父节点的值;
堆排序思想:
(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大,大根堆)。
(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。
时间复杂度:排序过程的时间复杂度是O(nlgn)。因为建堆的时间复杂度是O(n)(调用一次);调整堆的时间复杂度是lgn,调用了n-1次,所以堆排序的时间复杂度是O(nlgn)[2]
public class test4 { public static void main(String[] args) { heapSort(new int[] { 1, 3, 7, 5, 2, 8, 4, 6, 10, 9 }); } //调整堆:利用的思想是比较节点parent和它的孩子节点left(parent),right(parent),选出三者最大(或者最小)者,如果最大(小)值不是节点parent而是它的一个孩子节点,那边交互节点parent和该节点,然后再调用调整堆过程,这是一个递归的过程。调整堆的过程时间复杂度与堆的深度有关系,是O(lgn)的操作,因为是沿着深度方向进行调整的。 public static void HeapAdjust(int[] array, int parent, int length) { int temp = array[parent]; // temp保存当前父节点 int child = 2 * parent + 1; // 先获得左孩子 while (child < length) { // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点 if (child + 1 < length && array[child] < array[child + 1]) { child++; } // 如果父结点的值已经大于孩子结点的值,则直接结束 if (temp >= array[child]) break; // 把孩子结点的值赋给父结点 array[parent] = array[child]; // 选取孩子结点的左孩子结点,继续向下筛选 parent = child; child = 2 * child + 1; } array[parent] = temp; } public static void heapSort(int[] list) { // 循环建立初始堆:这里循环遍历子树,从最靠后的子树开始调整,建立大根堆。 for (int i = list.length / 2; i >= 0; i--) { HeapAdjust(list, i, list.length); } // 进行n-1次循环,完成排序 for (int i = list.length - 1; i > 0; i--) { // 最后一个元素和第一元素进行交换 int temp = list[i]; list[i] = list[0]; list[0] = temp; // 筛选 R[0] 结点,得到i-1个结点的堆 HeapAdjust(list, 0, i); System.out.println(Arrays.toString(list)); } }}
阅读全文
0 0
- 堆及堆排序
- 堆/堆排序特点
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆与堆排序
- 堆和堆排序
- 堆排序(最大堆)
- 堆和堆排序
- 堆和堆排序
- 堆及堆排序
- 堆和堆排序
- 堆与堆排序
- 学习博客园开源代码笔记(一)
- clone()的使用
- this web application instance has been stopped already. Could not load net.sf.ehcache.store.compoun
- c++构造函数的初始化列表
- tensorflow.layers.batch_normalization使用方法
- 堆排序
- 说说 Java I/O 系统——读写文件的实用工具
- 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
- 【备忘】2017麦子学院python编程视频VIP教程
- 图片无缝向右滚动
- SBL中的HAL和DAL层
- 多态、接口
- android 系统打开USB调试模式
- UWA 六月直播季 | 6.29 Unity UI模块中的优化案例精讲