热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

堆排序时间复杂度_学习笔记详解堆排序

本文目的上一章节已经详细的向大家介绍过排序的相关概念(详见学习笔记-排序简单介绍),本文旨在为大家详细的介绍堆排序。堆排序堆排序(英语:Heapsort

本文目的

上一章节已经详细的向大家介绍过排序的相关概念(详见学习笔记-排序简单介绍) ,本文旨在为大家详细的介绍堆排序。

堆排序

堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

堆是什么

堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆是一种非线性结构。可以把堆看作一个数组,也可以被看作一个完全二叉树,通俗来讲堆其实就是利用完全二叉树的结构来维护的一维数组。此处用到的堆一般是指大顶堆或小顶堆。

大顶堆

每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆。如下图所示。

7f4ad0f91de9f02f1fe6809ef995a161.png

小顶堆

每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图所示。

ffa032512539ef256385720d64e71379.png

算法原理

将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值,如此反复执行,便能得到一个有序序列了。需要注意的是建立大顶堆时是从最后一个非叶子节点开始从下往上调整的。

算法流程

1. 创建一个堆 R[0……n-1];

2. 把堆首(最大值)和堆尾互换;

3. 把堆的尺寸缩小 1(已经有序的部分不进入下一轮);

4. 重复步骤 2,直到堆的尺寸为 1。

c12d2f3386fd883e1453590db3a3f950.png

算法实现

操作过程如下:

1,初始化堆:将R[1..n]构造为堆;

2,将当前无序区的堆顶元素R[1]同该区间的最后一个记录交换,然后将新的无序区调整为新的堆。

#include #define elemType int /*元素类型*/int k=1;//轮次记录 //打印函数 void Print (elemType arr[], int len){int i;for (i=0; i a[son]){ return;}else{//否则交换父子内容再继续子节点和孙节点比较 swap(&a[dad], &a[son]); dad = son; son = dad * 2 + 1; } }} //排序 void Sort(elemType a[], int len){ int i; //初始化,i从最後一个父节点开始调整 for (i = len / 2 - 1; i >= 0; i--){ max_heapify(a, i, len - 1); } for (i = len - 1; i > 0; i--) { //先将第一个元素和已排好元素前一位做交换,再重新调整,直到排序完毕 swap(&a[0], &a[i]); max_heapify(a, 0, i - 1); printf("第===%d===轮排序后结果如下:",k);Print (a, 9);k=k+1; }}int main() {int i; elemType arr[9] = {94,19,29,9,11,1,14,13,29}; printf("待排序的序列为:"); Print(arr, 9); printf(""); Sort (arr,9); printf(""); printf("排好序的结果如下:"); Print(arr, 9); }

681802307fb12d4af5267f01b8df04d0.png

算法分析

时间复杂度

堆排序的运行时间主要是消耗在构建堆和在重建堆时的反复筛选上。在构建堆的过程,因为我们是从完全二叉树最下层的非叶子结点开始构建的,将它与其孩子结点进行比较和有必要的互换,对于每个非叶子结点来说,其实最多2次比较和互换,故初始化堆的时间复杂度为O(n)。在正式排序的时候,第i次取堆顶记录和重建堆需要O(logi)的时间(完全二叉树的某个结点到根结点的距离为log2i+1),并且需要取n-1次堆顶记录,因此重建堆的时间复杂度为O(nlogn)。所以总的来说,堆排序的时间复杂度为O(nlogn)。由于堆排序对元素记录的排序状态不敏感,因此它无论最好,最坏,和平均时间复杂度均为O(nlogn)。

空间复杂度

堆排序中只有交换元素时需要1个辅助空间,与问题规模无关,空间复杂度为O(1)。

排序稳定性

在构建堆的过程中无法保证相同值构建前后的相对位置,所以堆排序是不稳定的。

本文的初衷为学习笔记的分享,部分图文来源于网络,如侵,联删。



推荐阅读
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了最长上升子序列问题的一个变种解法,通过记录拐点的位置,将问题拆分为左右两个LIS问题。详细讲解了算法的实现过程,并给出了相应的代码。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • JVM:33 如何查看JVM的Full GC日志
    1.示例代码packagecom.webcode;publicclassDemo4{publicstaticvoidmain(String[]args){byte[]arr ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 本文介绍了一个程序,可以输出1000内能被3整除且个位数为6的所有整数。程序使用了循环和条件判断语句来筛选符合条件的整数,并将其输出。 ... [详细]
author-avatar
农村的企业家
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有