当前位置: 首页 > news >正文

二叉树从入门到AC(3)完全二叉树与堆

完全二叉树与堆

    • 前言
    • 优先队列:堆
    • 向下调整维护堆
    • 向上调整维护堆
    • 堆的作用

前言

本文算是补充之前的系列,在前文中,讲了二叉树的基本结构与应用
二叉树从入门到AC(1)构建和前中后序遍历
二叉树从入门到AC(2)深度与层次遍历
二叉树的特殊形态
二叉树有两种常用的特殊形态:满二叉树和完全二叉树。如果一颗二叉树,其内部每个结点都有左右儿子,我们称之为满二叉树,这很好理解,如图所示:
在这里插入图片描述

我们在满二叉树中的最后一层,从右往左连续拔去至少零个结点,便是完全二叉树。也就是说,满二叉树是一种特殊的完全二叉树
在这里插入图片描述
以上都为完全二叉树
那么如何判断一棵树是不是完全二叉树呢?我们可以运用层次遍历的结构(前文有代码),首先将储存一颗非空树,在队列中遵循:
1.如果遇到一个结点,左孩子为空,右孩子不为空,则该树一定不是完全二叉树
2.如果遇到一个结点,左孩子不为空,右孩子为空;或者左右孩子都为空,且则该节点之后的队列中的结点都为叶子节点,该树才是完全二叉树
3.以上两个一直都没触发,说明是满二叉树

优先队列:堆

堆,是一种特殊的完全二叉树,每个结点储存一个值,其中,若所有父结点都小于其子结点,称为最小堆,反之则是最大堆。如图:
在这里插入图片描述
二叉堆是一种基础数据结构,C++ 的STL中的优先队列就是使用二叉堆。另外,堆排序也是一种二叉堆算法。
堆的作用主要面向一个问题:如何高效的在一组数据中任意插入删除任何值的情况下,始终找到最小值/最大值。
这种数据结构也被称为优先队列。

向下调整维护堆

以上图的最小堆为例,在数组中按层次遍历储存为3,5,7,9,8,11
要求:不限次数的删除最小值并插入进新的值,保持堆的属性(最小值在堆顶)
这时候我们删除堆顶的最小值3,并且添加任意一个数如10到堆顶,只要能维护这个堆的属性,我们就可以得到新的最小值。
于是设计算法,我们从堆顶开始反复执行:把当前结点与左右儿子比对,并与最小的那个结点交换值,直到无法交换(要么是左右儿子都更大,要么是到叶子结点了)
如图所示:
在这里插入图片描述
于是我们维护住了一个最小堆,最大堆也是同理。那么在代码层就好写多了,我们可以根据数组下标发现,设当前结点下标为i,我们只需要每次与2i和2i+1相比并判断是否Swap就好
在这里插入图片描述

void Sswap(int a,int b)
{int c=0;c=arr[b];arr[b]=arr[a];arr[a]=c;
}
void siftdown(int i)//向下调整,用于寻找最值
{int t=0,flag=0;while(i*2<=n&&flag==0){if(arr[i]>arr[i*2])t=i*2;elset=i;if(t*2+1<=n){if(arr[t]>arr[i*2+1])t=i*2+1;}if(t!=i){Sswap(t,i);//交换两结点的值i=t;}elseflag=1;}
}

在主函数中,我们将数组调整为全局变量,并且i始终设为0,例如

int arr[6]={10,5,7,9,8,11};
int n=5;
int main()
{siftdown(0);for(int i=0;i<=n;i++){printf("%d ",arr[i]);}return 0;
}

执行结果:
在这里插入图片描述

向上调整维护堆

如果我们需要不断向堆中添加数值而不删除数值怎么办?那么我们可以从下面的叶子结点开始添加,并逐一往上比对,来维护堆。

void siftup(int i)
{int flag=0;if(i==0)return;while(i!=0&&flag==0){if(arr[i]<arr[i/2])Sswap(i,i/2);elseflag=1;i=i/2;}
}

我们将:arr[6]={3,5,7,9,8,1};
与i=5代入,
在这里插入图片描述

这便是堆的维护操作。

堆的作用

当我们输入一个数组,并求其最值时,我们一般会开max或min比对每个数并保留最值,这是时间复杂度最低的做法,为O(N)。但是当我们删除最小值并添加进一个新值之后,就相当于需要彻底进行一次重新排序,复杂度也来到了O(N^2),而同样的目的,由于堆的特性,维护起来只需要logN的时间。
那么我们如何用完全无序的数列建立一个堆呢?

void creat()
{int i=0;for(i=n/2;i>=0;i--){siftdown(i);}
}

即可。
在创建了堆之后,我们还有著名的排序方法,堆排序,网上到处都有模板在这里不赘述。另外,堆也是一种重要的优化思路出现在别的算法中,主旨都在于用更短的时间来在插入、删除元素的情况下捕捉最值(或者第n大的值也可以)。

相关文章:

二叉树从入门到AC(3)完全二叉树与堆

完全二叉树与堆 前言优先队列&#xff1a;堆向下调整维护堆向上调整维护堆堆的作用 前言 本文算是补充之前的系列&#xff0c;在前文中&#xff0c;讲了二叉树的基本结构与应用 二叉树从入门到AC&#xff08;1&#xff09;构建和前中后序遍历 二叉树从入门到AC&#xff08;2&a…...

AI写作:如何让创作过程更流畅?

写作这件事一直让我们从小学生头痛到打工人&#xff0c;初高中时期800字的作文让我们焦头烂额&#xff0c;一篇作文里用尽了口水话&#xff0c;拼拼凑凑才勉强完成。 大学时期以为可以轻松顺利毕业&#xff0c;结果毕业前的最后一道坎拦住我们的是毕业论文&#xff0c;苦战几个…...

2024中国海洋装备展暨航海装备大会(福州海峡国际会展中心)

关于邀请参加2024中国海洋装备博览会的函 为加快推动海洋强国建设。在福建省人民政府的大力支持下,第二届中国海洋装备博览会将于2024年11月15-18日在福州举办。 博览会将进一步聚焦产业链和供应链协同创新&#xff0c;着力推动现代海洋产业体系建设&#xff0c;促进海洋科技…...

CyberDAO:引领Web3时代的DAO社区文化

致力于Web3研究和孵化 CyberDAO自成立以来&#xff0c;致力于推动Web3研究和孵化&#xff0c;吸引了来自技术、资本、商业、应用与流量等领域的上千名热忱成员。我们为社区提供多元的Web3产品和商业机会&#xff0c;触达行业核心&#xff0c;助力成员捕获Web3.0时代的红利。 目…...

测试面试点

在面试PC端测试人员时&#xff0c;你可以提出以下具体问题来深入了解候选人的技能、经验和思维方式&#xff1a; 1. 技术能力与基础知识 你能解释一下什么是黑盒测试和白盒测试吗&#xff1f;你在过去的工作中是如何应用这两种测试方法的&#xff1f; 答案&#xff1a;黑盒测…...

Nginx配置详细解释:(4)高级配置

目录 1.网页的状态页 2.Nginx第三方模块(echo) 3.变量 4.自定义访问日志 5.Nginx压缩功能 6.https功能 7.自定义图标 Nginx除了一些基本配置外&#xff0c;还有一些高级配置&#xff0c;如网页的状态&#xff0c;第三方模块需要另外安装&#xff0c;支持变量&#xff0c…...

OceanBase 4.3 特性解析:列存技术

在涉及大规模数据的复杂分析或即时查询时&#xff0c;列式存储是支撑业务负载的关键技术之一。相较于传统的行式存储&#xff0c;列式存储采用了不同的数据文件组织方式&#xff0c;它将表中的数据以列为单位进行物理排列。这种存储模式允许在分析过程中&#xff0c;查询计算仅…...

ARM32开发--PWM与通用定时器

知不足而奋进望远山而前行 目录 文章目录 前言 学习目标 学习内容 PWM pwm原理 需求 开发流程 初始化PWM PWM占空比控制 main函数修改duty 输出通道 关心的内容 重要的关键词 周期 分频 占空比 总结 前言 在微控制器开发中&#xff0c;理解和掌握PWM&#x…...

debugger(七):栈帧(backtrace)

〇、前言 在前面已经详细得介绍了栈帧&#xff0c;这里实现 backtrace。 一、backtrace 思路是遍历 stack&#xff0c;搜索 stack pointer&#xff0c;逐个打印栈帧信息&#xff0c;一直打印到 main 函数。 void Debugger::print_backtrace() {auto output_frame [frame_n…...

kafka-重试和死信主题(SpringBoot整合Kafka)

文章目录 1、重试和死信主题2、死信队列3、代码演示3.1、appication.yml3.2、引入spring-kafka依赖3.3、创建SpringBoot启动类3.4、创建生产者发送消息3.5、创建消费者消费消息 1、重试和死信主题 kafka默认支持重试和死信主题 重试主题&#xff1a;当消费者消费消息异常时&…...

electron-Vue: Module parse failed: Unexpected character ‘ ‘

​ electron-Vue项目中&#xff0c;我自己写了一个node的C扩展&#xff08;xx.node&#xff09;&#xff0c;然后在.vue文件里import它&#xff0c;然后运行npm run electron:serve&#xff0c;报错如下: ​​ electron-Vue打包默认使用webpack&#xff0c;默认情况下webpack没…...

贪心算法-数组跳跃游戏(mid)

目录 一、问题描述 二、解题思路 1.回溯法 2.贪心算法 三、代码实现 1.回溯法实现 2.贪心算法实现 四、刷题链接 一、问题描述 二、解题思路 1.回溯法 使用递归的方式&#xff0c;找到所有可能的走步方式&#xff0c;并记录递归深度&#xff08;也就是走步次数&#x…...

C++经典150题

经典150题 数组/字符串 文章目录 经典150题数组/字符串88. 合并两个有序数组27.移除元素26.删除有序数组中的重复项80.删除有序数组重点重复项II169.多数元素189.轮转数组121.买卖股票的最佳时机123.买卖股票的最佳时机 III55.跳跃游戏45.跳跃游戏II 88. 合并两个有序数组 给…...

超详解——Python 序列详解——基础篇

目录 1. 序列的概念 字符串&#xff08;String&#xff09; 列表&#xff08;List&#xff09; 元组&#xff08;Tuple&#xff09; 2. 标准类型操作符 连接操作符&#xff08;&#xff09; 重复操作符&#xff08;*&#xff09; 索引操作符&#xff08;[]&#xff09; …...

DVWA-DC-6

靶机IP:192.168.20.140 kaliIP:192.168.20.128 网络有问题的可以看下搭建Vulnhub靶机网络问题(获取不到IP) 信息收集 nmap扫描靶机端口及版本信息 dirsearch扫目录 发现是个wordpress建站 我们去访问前端界面 存在重定向&#xff0c;修改hosts文件&#xff0c;加入192.168…...

ubuntu早期版本以及18.04后的版本,通过rc.local配置开机自启

在ubuntu早期版本以及18.04后的版本&#xff0c;还是支持在rc.local中进行操作开机自启。 1、编辑rc.local文件 cat <<EOF >/etc/rc.local #!/bin/sh -e # rc.local # This script is executed at the end of each multiuser runlevel. # Make sure that the script…...

【环境搭建】1.阿里云ECS服务器 安装jdk8

在阿里云服务器上安装 JDK 8 可以通过以下步骤完成。假设你使用的是 CentOS 或者其他基于 Red Hat 的发行版或Alibaba Cloud Linux 3.2104 LTS 64位。 1.更新系统软件包 sudo yum update -y2.安装 OpenJDK 8 使用 yum 包管理器安装 OpenJDK 8 sudo yum install -y java-1.8…...

idea插件开发之定义侧边栏

写在前面 看下如何在侧边栏定义窗口&#xff0c;如下的效果&#xff1a; 1&#xff1a;正戏 先来定义UI&#xff0c;随便拖拽个组件&#xff0c;就看个效果&#xff1a; 接着定义一个工厂类来创建这个UI&#xff0c;需要实现接口com.intellij.openapi.wm.ToolWindowFactor…...

HarmonyOS未来五年的市场展望

一、引言 随着科技的不断进步和消费者对于智能化设备需求的日益增长&#xff0c;操作系统作为连接硬件与软件的核心平台&#xff0c;其重要性愈发凸显。HarmonyOS&#xff08;鸿蒙系统&#xff09;&#xff0c;作为华为自主研发的分布式操作系统&#xff0c;自诞生以来便备受瞩…...

R语言:什么是向量化操作(Vectorization)?

在R语言中&#xff0c;向量化操作是一个非常重要且强大的概念。它不仅提高了代码的简洁性和可读性&#xff0c;还大大提升了代码的执行效率。本文将详细介绍什么是向量化操作&#xff0c;并通过几个示例来展示其应用。 什么是向量化操作&#xff1f; 向量化操作是指在不使用显…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...