【数据结构】八大排序之堆排序算法

🦄个人主页:修修修也

🎏所属专栏:数据结构

⚙️操作环境:Visual Studio 2022


目录

一.堆排序简介及思路

二.堆排序的代码实现

三.堆排序的时间复杂度分析

结语


一.堆排序简介及思路

堆排序(Heap Sort)是一种效率较高的选择排序算法.

它是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它通过堆来进行选择数据.

有关还不了解的朋友可以先移步这篇文章:【数据结构】什么是堆?

它的基本思想是:

  1. 将待排序的序列构造成一个大堆.(如果是降序则建小堆)
  2. 此时,整个序列的最大值就是堆顶的根结点.将它移走(其实就是我们前面堆实现中的出堆顶操作).
  3. 然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次小值(即堆顶).
  4. 如此反复执行,就可以得到一个有序的序列了.

算法动图演示:

1.向下调整建堆

逻辑结构:

物理结构:

2.堆排序(升序)

逻辑结构:

物理结构:


二.堆排序的代码实现

算法实现步骤:(以升序为例)

  1. 从最后一个叶子结点的双亲节点开始向前遍历并向下调整建堆.
  2. 建堆完成后,将堆顶元素与待排序列的最后一个元素做交换.
  3. 交换后缩小待排序列范围,使刚刚交换到最后的堆顶元素不再参与后续的堆排序.
  4. 重新将新堆顶元素向下调整,使堆恢复为大堆.
  5. 重复2-4步骤,直到数组完全有序.

搞清实现步骤后,代码的实现就比较简单了,堆排序代码如下:

//交换函数
void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}//向下调整建堆
void AdjustDown(int* a, int n, int parent)
{int child = parent * 2 + 1;//默认是左孩子while (child < n)//孩子走到叶子就可以停止了{//选出左右孩子中大的那个if (child + 1 < n && a[child + 1] > a[child])//如果右孩子存在且大于左孩子{child++;}//向下调整重新使堆有序if (a[child] > a[parent])//建大堆{Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}//堆排序(升序
void HeapSort(int* a, int n)
{for (int i = (n - 1 - 1) / 2; i >= 0; i--)//先向下调整建堆{AdjustDown(a, n, i);}int end = n - 1;while (end > 0){Swap(&a[end], &a[0]);//将堆顶元素和待排区间的最后一个元素交换AdjustDown(a, end, 0);end--;}
}

三.堆排序的时间复杂度分析

堆排序方法对数据数较少的序列排序的效果并不很好,但对n较大的序列还是很有效的.

因为它的运行时间主要耗费在建初始堆和调整建堆时进行的反复"筛选"上.

         对深度为k的堆,筛选算法中进行的关键字比较次数至多为2(k-1)次,则在建含n个元素,深度为h的堆时,总共进行的关键字比较次数不超过4n.又因为n个结点的完全二叉树的深度为\left \lfloor log_{2}n \right \rfloor +1,则调整建新堆时调用向下建堆函数过程n-1次,总共进行的比较次数不超过下式:

2*(\left \lfloor log_{2}(n-1) \right \rfloor +\left \lfloor log_{2}(n-2) \right \rfloor+...+log_{2}2)<2n*(\left \lfloor log_{2}n \right \rfloor)

因此,堆排序在最坏的情况下,其时间复杂度也为O(nlogn),这是相对快排,堆排的最大优点.


结语

希望这篇堆排序算法详解能对大家有所帮助,欢迎大佬们留言或私信与我交流.

有关更多排序相关知识可以移步:

【数据结构】八大排序算法​​icon-default.png?t=N7T8https://blog.csdn.net/weixin_72357342/article/details/135038495?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135038495%22%2C%22source%22%3A%22weixin_72357342%22%7D&fromshare=blogdetail

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!

相关文章推荐

【数据结构】八大排序之冒泡排序算法

【数据结构】八大排序之希尔排序算法

【数据结构】八大排序之直接插入排序算法

【数据结构】八大排序之简单选择排序算法


数据结构排序算法篇思维导图:


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/284231.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java接收并解析HL7协议数据

一、前言 HL7协议相信医疗行业的IT人员都不陌生&#xff0c;笔者由于接触时间比较短&#xff0c;乍一听“协议”还是比较懵&#xff0c;不自觉就把它和“HTTP”、"SOAP”之类的网络协议挂上关联&#xff0c;可事实上这个HL7只是一种数据格式&#xff0c;传输方式也可以使用…

【运维笔记】mvware centos挂载共享文件夹

安装mvware-tools 这里用的centos安装 yum install open-vm-tools 设置共享文件夹 依次点击&#xff1a;选项-共享文件夹-总是启用-添加&#xff0c;安装添加向导操作添加自己想共享的文件夹后。成功后即可在文件夹栏看到自己共享的文件夹 挂载文件夹 临时挂载 启动虚拟机&…

OA、CRM、ERP之间的区别和联系是什么?

OA、CRM、ERP之间的区别和联系是什么&#xff1f; OA、CRM、ERP&#xff0c;这些系统都是用于提高企业运营效率和管理的工具&#xff0c;它们可能在某些功能上有重叠&#xff0c;比如 CRM 和 ERP 可能都涉及到客户数据管理&#xff0c;但它们的重点和功能侧重点是不同的。 我们…

SCC-Tarjan算法,强连通分量算法,从dfs到Tarjan详解

文章目录 前言定义强连通强连通分量 Tarjan算法原理及实现概念引入搜索树有向边的分类强连通分量的根时间戳追溯值 算法原理从深搜到TarjanTarjan算法流程Tarjan算法代码实现 OJ练习&#xff1a; 前言 强连通分量是图论中的一个重要概念&#xff0c;它在许多领域都有广泛的应用…

【mybatis】mapper.xml映射文件

目录 一.概述 二.了解mapper.xml文件 namespaceidresultType指定映射文件的路径 一.概述 mapper.xml 是一个 MyBatis 的映射文件&#xff0c;用于定义 SQL 语句和结果映射。它是一个 XML 文件&#xff0c;通常放置在项目的资源目录下。 随着mybatis框架的发展&#xff0c;myb…

SpringBoot的多环境开发

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

JupyterHub 如何切换 conda 小环境

JupyterHub 如何切换 conda 小环境 服务器已经部署好 JupyterHub &#xff0c;相关端口请看对应答疑群群公告。在Jupyterhub 中使用 conda 创建的小环境&#xff0c;首先 ssh 登录上服务器或者在 JupyterHub 网页端打开终端 terminal。然后安装 conda &#xff0c;方法请见 Q4&…

Android 一分钟使用RecyclerView完美实现瀑布

【免费】安卓RecyclerView瀑布流效果实现资源-CSDN文库 1.WaterfallFlowActivity 主函数代码&#xff1a; package com.example.mytestapplication;import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.widget.Toast;im…

【亲测好用】DevC++编译出现‘项目没有调试信息,您想打开项目调试选项并重新生成吗’完美解决

DevC不能正常编译 问题描述问题解决 问题描述 问题解决 工具->编译选项 编译器 添加 -g3 在下面命令框 代码生成/优化->链接器->将下面产生调试信息改为Yes 打开调试信息显示&#xff08;工具->环境选项->浏览Debug变量打开&#xff09; 最后一定一定要重新点击…

C语言学习第二十六天(算法的时间复杂度和空间复杂度)

1、算法效率 衡量一个算法的好坏&#xff0c;是从时间和空间两个方面来衡量的&#xff0c;换句话说就是从时间复杂度和空间复杂度来衡量的 这里需要补充一点&#xff1a;时间复杂度是衡量一个算法的运行快慢&#xff0c;空间复杂度是主要衡量一个算法运行所需要的额外空间。 …

Kafka消息延迟和时序性详解(文末送书)

目录 一、概括1.1 介绍 Kafka 消息延迟和时序性1.1.1 什么是 Kafka 消息延迟&#xff1f;1.1.2 为什么消息延迟很重要&#xff1f;1.1.3 什么是 Kafka 消息时序性&#xff1f;1.1.4 消息延迟和时序性的关系 1.2 延迟的来源1.2.1 Kafka 内部延迟 二、衡量和监控消息延迟2.1 延迟…

15.VLAN

VLAN 虚拟局域网 路由器可以隔离广播&#xff0c;但是二层设备交换机就不行了 划分VLAN缩小安全范围 例如发送ARP报文的时候&#xff0c;就只会发送给同一VLAN的设备&#xff0c;而不是整个网络中的所有设备 同一VLAN的用户可以互访&#xff0c;不同VLAN的用户默认是不能互…