数据结构学习记录——堆的建立(最大堆的建立、思路图解、代码实现、代码解释)

news2024/11/19 5:17:25

目录

最大堆的建立

方法1 

方法2

思路图解

代码实现 

代码解释

PercDown

BuildHeap


最大堆的建立

建立最大堆:将已经存在的N个元素按最大堆的要求存放在一个一维数组中。

方法1 

通过插入操作,将N个元素一个一个地插入到一个初始为空的堆中去。堆插入的时间复杂度为{log_{2}}^{N},插人N个元素,那么最终建立堆的时间复杂度就为O(N{log_{2}}^{N})

方法2

线性时间复杂度下建立最大堆。

(1)将N个元素按输入顺序存入,先满足完全二叉树的结构特性

(2)调整各结点位置,以满足最大堆的有序性

我们当然要选择更高效率的方法,下面就来看看方法2具体是怎样实现的:

思路图解

假设现在有12个元素,已经按输入顺序存入,满足了完全二叉树的结构特性:

对其进行调整,调整的思路和堆的删除相似,但是要从后往前开始,在左右两个堆中进行调整;我们从倒数第一个有儿子的结点开始调整。因为倒数第一个结点一定是只有左儿子或者有一个左儿子和一个右儿子,即左右两边一定是堆的结构

调整完倒数第一个有儿子 的结点之后,往上再进行调整。 

重复操作

继续往上,到上一层了。  

循环

 

最终调整完成 :

代码实现 

/* 下滤操作:将H中以H->Data[p]为根的子堆调整为最大堆 */
void PercDown( MaxHeap H, int p )
{ 
    int Parent, Child;
    ElementType X;

    X = H->Data[p]; /* 取出根结点存放的值 */
    for( Parent=p; Parent*2<=H->Size; Parent=Child )
    {
        Child = Parent * 2;
        if( (Child!=H->Size) && (H->Data[Child]<H->Data[Child+1]) )
        {
            Child++;  /* Child指向左右子结点的较大者 */
        }
        if( X >= H->Data[Child] ) 
        {
            break; /* 找到了合适位置 */
        }
        else
        {
            /* 下滤X */
            H->Data[Parent] = H->Data[Child];
        } 
    }
    H->Data[Parent] = X;
}

/* 将一个无序的数组调整为最大堆  */
void BuildHeap( MaxHeap H )
{ 
  /* 这里假设所有H->Size个元素已经存在H->Data[]中 */

    int i;

    /* 从最后一个结点的父节点开始,到根结点1 */
    for( i = H->Size/2; i>0; i-- )
        PercDown( H, i );
}

代码解释

PercDown

PercDown函数用于将以某个结点为根的子树调整为最大堆。

其中,参数p,表示要下滤的结点在H中的下标。

Parent表示当前结点的父结点,Child表示当前结点的子结点,X表示当前结点的值。

首先,将要下滤的结点的值X取出来,保存在一个临时变量中。 

 然后,从要下滤的结点开始,沿着其左右子结点中较大的一个不断下滤,

直到找到X的合适位置或者到达叶结点为止。(Child的判断那里与堆的删除那里是一致的)

具体来说,每次将要下滤的结点与其左右子结点中较大的一个进行比较,

如果X比较大,则说明X已经找到了合适的位置,可以退出循环;(最大堆根结点比左右子结点都要大)

否则,将较大的子节点上移一层,继续下滤。

 

最后,将X放到找到的合适位置上,完成下滤操作。

BuildHeap

BuildHeap函数用于将一个无序的数组调整为最大堆。

 

从倒数第一个没有儿子的结点开始,即从最后一个非叶子节点开始,依次进行下滤操作,将其子树调整为最大堆。

因为最后一个非叶子节点的数组下标为n/2,其中n为堆中元素的个数,所以从i=n/2开始循环。

循环执行,直到整个数组都被调整为最大堆。

综上,BuildHeap函数的时间复杂度为O(N),其中N为堆中元素的个数。因为每个结点最多只需要下滤一次,而下滤的时间复杂度为O({log_{2}}^{N}),所以建立一个最大堆,总的时间复杂度为O(N{log_{2}}^{N})。与开头所说相符合,效率较方法1要更高。


end


学习自:MOOC数据结构——陈越、何钦铭

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSA发布|《洞察2022 云上数据安全与重要事项 》

云安全联盟大中华区就云上数据安全和重要事项的洞察和建议等相关问题展开调查并发布《洞察2022 云上数据安全与重要事项 》&#xff08;以下简称《报告》&#xff09;。报告的主要内容是关于云上数据安全和重要事项的洞察和建议。它包括了对云安全现状的分析、云安全风险的评估…

git的学习

文章目录 一、Git 的简介二、Git 工作流程三、Git 工作区、暂存区和版本库总结 一、Git 的简介 Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软…

【c语言】字符串比较 | API仿真

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ …

RabbitMQ可靠性消息发送(java实现)

本博客属于 《RabbitMQ基础组件封装—整体结构》的子博客 一、整体架构 step1&#xff1a;消息落库&#xff0c;业务数据存库的同时&#xff0c;也要将消息记录存入数据库&#xff0c;二者要保证原子性&#xff1b; step2&#xff1a;Producer发送消息到MQ Broker&#xff1b…

Formik使用详解

Formik使用详解 1 引言 在现代Web应用程序中&#xff0c;表单是一种不可避免的输入机制&#xff0c;但是处理表单的过程可能会变得非常复杂。Formik是一个React表单库&#xff0c;它的目标是简化表单处理的过程。本文将介绍Formik的主要功能和用途&#xff0c;以及如何使用它来…

怎么成为一名架构师?架构师第一步。基层开发人员逆袭成为架构师真的很难吗?

文章目录 写在前面一、企业需要什么样的架构师1、从招聘软件上了解2、架构师的主要职责与能力 二、成为一名架构师很难吗1、架构师的定义2、当前大部分开发团队的现状3、为什么要有架构师4、技术人员如何自我突破 三、晨钟暮鼓的几句话 写在前面 一个团队中&#xff0c;每个人…

JAVA基础:Scanner类中next(), nextLine(), hasNext(), hasNextLine()

一、next() : 只读缓冲区中空格之前的数据,并且光标指向本行。二、nextLine() : 读取除回车以外的所有符号(整行内容)&#xff0c;光标定位在下一行三、hasNext() &#xff1a;检查下一个标记&#xff08;token&#xff09;&#xff0c;也就是以空格、制表符或换行符为分隔符的…

[JAVA EE]创建Servlet——实现Servlet接口笔记1

创建Servlet的方式之一&#xff1a;实现servlet接口 servlet的生命周期&#xff1a; 1、实例化&#xff1a;创建servlet实例对象 2、初始化&#xff1a;调用init方法完成初始化工作 3、服务&#xff1a;调用service方法来处理用户请求 4、销毁&#xff1a;调用destroy方法…

Java算法比赛常用方法

1. 开方&#xff1a;Math.sqrt(x); 2. x的a方&#xff1a;Math.pow(x,a); 3. 绝对值&#xff1a;Math.abs(x)&#xff1b; 4. BigInteger&#xff1a;大数&#xff08;加&#xff0c;减&#xff0c;乘&#xff0c;除&#xff0c;取余&#xff09; c.add(d) ; c.subtract(d)…

如何用100天彻底学会Python?

Python 是一门功能强大、易于学习且历史悠久的编程语言。如果你希望在短时间内彻底学会 Python&#xff0c;需要制定一个全面的学习计划&#xff0c;并进行刻意的练习和实践。 以下是一份建议的学习计划&#xff0c;帮助你在 100 天内掌握 Python 技能。 第 1-10 天&#xff…

从bootamition出发分析OpenHarmony下Gralloc buffer管理机制

从bootamition出发分析OpenHarmony下Gralloc buffer管理机制 引言 这个文档主要记录从bootamition角度出发&#xff0c;分析OpenHarmony下对gralloc buffer的管理&#xff01;由于OpenHarmony图形子系统过于复杂&#xff0c;且个人由于能力有限&#xff0c;这里我仅从gralloc b…

2023.03青少年机器人技术等级考试理论综合试卷(五级)

2023年3月青少年机器人技术等级考试理论综合试卷&#xff08;五级&#xff09; 一、单选题(共 20 题&#xff0c;共 80 分) 1. 0x35 & 7 的结果是&#xff1f;&#xff08;A &#xff09; A. 5 B. 55 C. 50 D. 54 2.一般状况下&#xff0c;关于主控板的工作电压&#xff0c…

「 Redis 」大key对持久化有什么影响?

「 Redis 」大key对持久化有什么影响&#xff1f; 参考&鸣谢 Redis 大 Key 对持久化有什么影响&#xff1f; XiaoLinCoding 解决了Redis大key问题&#xff0c;同事们都夸他牛皮 大白斯基 快手面试官&#xff1a;Redis变慢了&#xff0c;如何快速排查&#xff1f; Java 那些…

Vue 2.0 学习笔记

Vue学习笔记 文章目录 Vue学习笔记[toc]一、数据代理实现二、事件相关1.事件修饰符2.键盘事件 三、计算属性与监视1.计算属性-computed2.监视-watch 四、条件渲染1.v-show2.v-if&#xff0c;v-else-if 五、循环遍历1.v-for语法2.key的作用与原理 六、内置指令1.v-cloak指令&…

使用GitHub分享项目

一、注册账户 访问GitHub网站&#xff0c;点击“Sign up”按钮开始注册账号。然后按照提示输入你的用户名、电子邮箱地址和密码&#xff0c;提交成功后通过邮箱或你注册的手机号码进行验证身份。 二、上传项目 想分享自己的项目&#xff0c;首先需要在GitHub上创建一个新的仓库…

React + ts学习笔记

前提准备&#xff1a; 环境配置 安装node.js 官网安装&#xff1a;当前使用版本18.15.0 安装新的react应用&#xff1a; 运行命令新建react-app npx create-react-app study-ts-app当前版本&#xff1a; “react”: “^18.2.0”,“react-dom”: “^18.2.0”, 如果出现如…

优维低代码实践:第一个微应用

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

vue-element-admin踩坑合集+完整包(项目源码 +依赖)

目录 Nodejs版本&#xff1a; 安装依赖时遇到的报错&#xff1a; 启动报错&#xff1a; vue-element-admin完整包地址&#xff1a; 在部署安装使用vue-element-admin开源项目的时候&#xff0c;会遇到各种各样的问题。 这里是本人遇到的一些坑。。。。。。 Nodejs版本&am…

【技术碎片】【Java】计算椭圆的外接矩形坐标

目录 前言原生实现&#xff08;错误方法&#xff09;精确实现&#xff08;数学解&#xff09;参考 前言 遇到一个需要计算一般椭圆&#xff08;斜椭圆&#xff09;的外接矩形坐标的问题&#xff0c;在此记录一下 已知椭圆的中心点坐标centerX centerY&#xff0c;椭圆的长轴&…

FPGA - 7系列 FPGA内部结构之CLB -02- CLB功能详解

前言 本文翻译自UG474第二章&#xff0c;主要对7系列FPGAs CLB结构进行详细介绍。这些细节对设计优化和验证很有帮助。 CLB 排列 CLB 在 7 系列 FPGA 中按列排列。 7 系列是基于 ASMBL架构提供的独特柱状方法的第四代产品。ASMBL 架构 Xilinx 创建了高级硅模块块 (ASMBL) 架…