【数据结构:排序算法】堆排序(图文详解)

🎁个人主页:我们的五年

🔍系列专栏:数据结构课程学习

🎉欢迎大家点赞👍评论📝收藏⭐文章

目录

🍩1.大堆和小堆

🍩2.向上调整算法建堆和向下调整算法建堆:

🍟向上调整算法:

🍟向下调整算法:

🍟用这两种方法建堆的时间复杂度:

🍩3.堆排序:


 

🍩1.大堆和小堆

要想弄明白堆排序,我们先来看看大堆和小堆的概念和区别: 

注意:堆是完全二叉树。

大堆:父节点都大于孩子节点。

小堆:父节点都小于孩子节点。

🍩2.向上调整算法建堆和向下调整算法建堆:

注:根节点我定为0

🍟向上调整算法:

向下调整算法调整该节点的前提是该节点以上的树已经是堆(大堆或者小堆),但是开始的时候,树里面的元素是随便放置的,但是可以把根元素以上看成一个堆,然后向上调整从2*0+1(第二层左边的元素)的位置开始就可以了。


以向上调整建立大堆为例:

从已经建好的堆的下一层开始向上调整,这里可以把根看成小堆,要想把整个二叉树调整为小堆形式,我们就要从根的下一层,把每个元素都进行一次向上调整。

向上调整的实现:

根该节点开始,我们把该节点与它的父节点进行比较,因为该节点以上的节点已经是大堆,此时的根是该树最大元素,所以只要和根比较谁大,如果比根大就交换位置,这样增加一个元素以后,该树还是大堆。

从上面图来看,向上调整结束的条件为该节点到达根节点,上面没有元素了。

由孩子节点的下标找到父节点的下标是:parent=(child-1)/2。

实现代码:

void AdjustUp(int* a,int child)
{//该节点开始比较int parent = (child - 1 - 1) / 2;while (child > 0)	//当节点到达根节点,就没有父亲节点了,就停止{if (a[parent] < a[child]){int tmp = a[parent];a[parent] = a[child];a[child] = a[parent];child = parent;parent = (child - 1 - 1) / 2;}else{break;}}
}

🍟向下调整算法:

向下调整算法的要求就是左右子树已经是堆(大堆或者小堆)。结束的条件是孩子节点为NULL。

代码为:
 

void AdjustDown(int* a, int size, int parent)
{//假设法int child = parent * 2 + 1;while (child < size){if (child + 1 < size && a[child + 1]>a[child]){++child;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

🍟用这两种方法建堆的时间复杂度:

假如待排序的二叉树有K层,假设为满二叉树:
如果用向
上调整算法,那么进行的次数是:

第1层:2^0*0        //2的0次方这这一层的节点个数,0是调整的次数,根节点向上调整的时候 ,不需要调整。

第2层:2^1*1

……

第K层:2^(k-1)*k-1

所以总的次数为:

2^0*0+2^1*1+2^2*2+……+2^(k-1)*k=(k-1)*2^k-2.

个数N=2^k-1.k=log2 (N+1)

所以O(N)=(log2 (N+1)-1)*(N+1)-2。

数量级在log N

所以O(N)=N*log N。

向下调整:

其实用向下,就可以让节点最多的调整次数最少,也就是:多*少,少*多。

而向上调整,就是:多*多,少*少。第一层的节点少,不用调整,第二层两个节点,每个调整一次,后面节点多,每个节点调整次数也多。

第k-1层:2^(k-2)*1。

第k-2层:2^(k-3)*2。

……

第2层2^1*(k-2)。

第1层2^0*(k-1)。

总的:2^0*(k-1)+2^1*(k-2)+……+2^(k-2)*1=2^k+2*k-4。

O(N)=log N。

根据上面的结论,我们知道如果要建堆,那肯定是用向下调整更好。

🍩3.堆排序:

用向下排序拍好序以后,如果我们要排升序,我们就建大堆,如果我们要排降序,我们就排小队堆。

升序:大堆。

降序:小堆。

我们以升序为例:

当得到大堆的时候,根节点是最大的,然后我们把根节点和最后的节点换一下位置,这样最大的就到最后面去了,然后我们换完以后,又用向下调整使除最后一个节点以外为大堆,这样我们取根节点,我们就的得到了第二大的,我们就把第二大的和数组的倒数第2的位置换位置,然后再让根节点向下调整建立大堆……

这样我们就能让数组升序,代码实现:

void Swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}void AdjustDown(int* a, int size, int parent)
{//假设法int child = parent * 2 + 1;while (child < size){if (child + 1 < size && 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[0], &a[end]);AdjustDown(a, end, 0);--end;}
}

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

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

相关文章

网络应用层之(1)DHCPv6协议

网络应用层之(1)DHCPv6协议 Author: Once Day Date: 2024年5月26日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 通信网络技术_Once-Day的博客-C…

【使用ChatGPT构建应用程序】应用程序开发概述:1. 管理秘钥、2. 数据安全、3. 与应用程序解耦、4. 注意提示语的注入攻击

文章目录 一. 首先注意的两个方面1. 管理API密钥1.1. 用户提供API密钥1.2. 你自己提供API密钥 2. 数据安全和数据隐私 二. 软件架构设计原则&#xff1a;与应用程序解耦三. 注意LLM提示语的注入攻击1. 分析输入和输出2. 监控和审计3. 其他要注意的注入情况 在了解了ChatGPT的文…

easy-rule规则引擎使用

简介 轻量级的规则引擎&#xff0c;易于学习的api 简单来说&#xff0c;规则引擎就是一个函数&#xff1a;yf(x1,x2,…,xn) 将业务代码和业务规则分离&#xff0c;解耦业务决策和业务代码的绑定关系 入门示例 依赖引入 <dependency><groupId>org.jeasy</grou…

css卡片翻转 父元素翻转子元素不翻转效果

css卡片翻转 父元素翻转子元素不翻转效果 vue <div class"moduleBox"><div class"headTitle"><span class"headName">大额案例</span></div><div class"moduleItem"><span class"module…

数据结构 | 详解二叉树——堆与堆排序

&#x1f95d;堆 堆总是一棵完全二叉树。 大堆&#xff1a;父节点总是大于子节点。 小堆&#xff1a;父节点总是小于子节点。 注意&#xff1a;1.同一个节点下的两个子节点并无要求先后顺序。 2.堆可以是无序的。 &#x1f349;堆的实现 &#x1f334;深度剖析 1.父节点和子…

Gir clone 设置代理与错误

git查看、配置、删除代理 link git config --global https.proxy http://127.0.0.1:1080 git config --global http.proxyhttps://stackoverflow.com/questions/11265463/reset-git-proxy-to-default-configuration git config --global --unset http.proxy git config --gl…

Spring-注解

Spring 注解分类 Spring 注解驱动模型 Spring 元注解 Documented Retention() Target() // 可以继承相关的属性 Inherited Repeatable()Spirng 模式注解 ComponentScan 原理 ClassPathScanningCandidateComponentProvider#findCandidateComponents public Set<BeanDefin…

数据源不同?奥威BI软件是这么做的

面对数据源不同的情况&#xff0c;BI&#xff08;商业智能&#xff09;软件如奥威BI软件通常通过一系列技术和方法来实现数据的整理。以下以奥威BI软件为例&#xff0c;详细解释其如何整理不同数据源的数据&#xff1a; 数据收集&#xff1a; 爬虫技术&#xff1a;奥威BI软件…

Java程序设计

一 Java基础知识 1 Java语言概述 1.1 发展历史 1.2 Java应用领域 Web开发&#xff1a;电子商务网站、内部管理系统、社交网络、门户网站移动开发&#xff1a;Android开发桌面开发&#xff1a;办公软件、游戏、工具软件企业应用开发&#xff1a;客户关系管理、企业资源计划、…

【数据结构】探索树中的奇妙世界

专栏介绍&#xff1a; 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累…

redis 集群 底层原理以及实操

前言 上篇我们讲解了哨兵集群是怎么回事 也说了对应的leader选举raft算法 也说了对应的slave节点是怎么被leader提拔的 主要是比较优先级 比较同步偏移量 比较runid等等 今天我们再说说,其实哨兵也有很多缺点 虽然在master挂了之后能很快帮我们选举出新的master 但是对于单个ma…

C#解析JSON的常用库--Newtonsoft.Json

一、库介绍 在C#中&#xff0c;解析JSON的常用库有Newtonsoft.Json&#xff08;也称为Json.NET&#xff09;和 System.Text.Json&#xff08;从 .NET Core 3.0 开始引入&#xff09;。本文主要介绍 Newtonsoft.Json。 二、下载 官网&#xff1a; https://www.nuget.org/pack…

解决文件传输难题:如何绕过Gitee的100MB上传限制

引言 在版本控制和代码托管领域&#xff0c;Gitee作为一个流行的平台&#xff0c;为用户提供了便捷的服务。然而&#xff0c;其对单个文件大小设定的100MB限制有时会造成一些不便。 使用云存储服务 推荐理由&#xff1a; 便捷性&#xff1a;多数云存储服务如&#xff1a; Dro…

Vue——事件修饰符

文章目录 前言阻止默认事件 prevent阻止事件冒泡 stop 前言 在官方文档中对于事件修饰符有一个很好的说明&#xff0c;本篇文章主要记录验证测试的案例。 官方文档 事件修饰符 阻止默认事件 prevent 在js原生的语言中&#xff0c;可以根据标签本身的事件对象进行阻止默认事件…

隆道出席河南ClO社区十周年庆典,助推采购和供应链数字化发展

5月26日&#xff0c;“河南ClO社区十周年庆典”活动在郑州举办&#xff0c;北京隆道网络科技有限公司总裁助理姚锐出席本次活动&#xff0c;并发表主题演讲《数字化采购与供应链&#xff1a;隆道的探索与实践》&#xff0c;分享隆道公司在采购和供应链数字化转型方面的研究成果…

ZooKeeper安装

安装Zookeeper 1、下载Zookeeper安装包 打开链接选择一个版本进行下载 https://zookeeper.apache.org/releases.html2、上传Zookeeper安装包到集群 输入命令 scp apache-zookeeper-3.8.4-bin.tar.gz hadoop192.168.88.100:/tmp也可以使用xftp等上传&#xff0c;物理机用u盘…

方法的重写--5.29

当子类对父类的方法不满意时&#xff0c;可以进行重写&#xff0c;但是方法名字要与父类一样。 举例&#xff0c;我用people来举例&#xff0c;我是打工人&#xff0c;然后再创一个student类&#xff0c;重写方法我不是打工人&#xff0c;我是读书人。代码如下&#xff0c;发现…

如何让你的网站能通过域名访问

背景 当我们租一台云服务器&#xff0c;并在上面运行了一个Web服务&#xff0c;我们可以使用云服务器的公网IP地址进行访问&#xff0c;如下&#xff1a; 本文主要记录如何 实现让自己的网站可以通过域名访问。 买域名 可以登录腾讯云等主流公有云平台的&#xff0c;购买域名…

Matlab|基于PMU相量测量单元进行电力系统电压幅值和相角状态估计

主要内容 程序采用三种方法对14节点和30节点电力系统状态进行评估&#xff1a; ①PMU同步相量测量单元结合加权最小二乘法&#xff08;WLS&#xff09;分析电力系统的电压幅值和相角状态&#xff1b; ②并采用牛顿-拉夫逊方法进行系统潮流计算&#xff0c;结果作为理论分…

摩尔线程MTT S4000 AI GPU助力30亿参数大模型训练,性能比肩英伟达同类解决方案

中国国产GPU制造商摩尔线程(Moore Threads)在AI加速器领域取得了显著进展&#xff0c;其最新推出的MTT S4000 AI GPU在训练大规模语言模型时表现突出&#xff0c;据称相较于其前代产品有着显著的性能提升。根据cnBeta的报道&#xff0c;搭载S4000 GPU的全新“酷鹅千卡智能计算集…