二叉树介绍及堆

文章目录

概念及结构

二叉树

概念及结构

特殊的二叉树

完全二叉树

满二叉树

性质

储存

顺序存储

链式储存

概念及结构

小堆

大堆

建堆

向上调整建堆

向下调整建堆

TOPK问题

法一:

法二:


概念及结构

     树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树。

  • 树的第一个结点被称为根结点
  • 除根结点外,其余结点被分成M(M>0)个互不相交的集合T1、T2.....、Tm,其中每一个集合Ti(1<=i<=m)又是一颗结构与树类似的子树。所以树是用递归定义的。

0c5edabadecc481d86e09af44bbe8f33.png   

 下面是树的常见相关概念

7a50dc4d67ed4395bbd62bcf3934c304.jpg

  • 度:一个结点含有的子树的个数称为该结点的度。如上图:A的度为6。
  • 叶结点:度为0的节点称为叶结点。如上图:P是叶结点。
  • 子结点:一个结点含有的子树的根结点称为该结点的子结点。如上图:B是A的子结点。
  • 父结点:若一个结点含有子结点,则这个结点称为父结点。如上图:A是B的父结点。
  • 树的高度或深度:树中节点的最大层次。如上图:该树的高度是4。

     注意:子树之间不能有交集(F只能有一个父结点)。

7e5511d35f1c4271afdfa30c2fbe7684.png

二叉树

概念及结构

     二叉树是一种特殊的树,其特点是每个结点最多只能有棵子树,且有左右之分。所以二叉树是有序树

9d77e0ea9a4249cd946a93c8c119107a.png

     一般称左边的树为左子树,右边为右子树最上边的结点是根结点。

c93aa9b0f0204989b79f4f1a376d3953.png

特殊的二叉树

完全二叉树

     假设该树有h层,则前h-1层的结点数都达到了最大,第h层结点连续集中在左边。

aaf756e7f864416d921ff0e4d407ccea.png

满二叉树

     如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。

     满二叉树是属于完全二叉树的。

c5dc249ad1704e55b684de6af05c73e8.png

性质

     1.若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)个结点。

     2. 若规定根结点的层数为1,则深度为h的二叉树的最大结点数是 2^h-1

     3. 对任何一棵二叉树, 如果度为0其叶结点个数为N0 , 度为2的分支结点个数为N2 ,则有N0 = N2+1

     4. 若规定根结点的层数为1,具有n个结点的满二叉树的深度,h= log2(n+1)。(log以2为底,n+1为对数)

     5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有结点从0开始编号,则对于下标i的结点有:

       (1)若i>0,i位置结点的父结点序号:(i-1)/2;若i=0,i为根结点无父结点。

       (2)若2*i+1<n,左孩子序号:2i+1,若2*i+1>=n否则无左孩子。

       (3)若2*i+2<n,右孩子序号:2i+2,若2*i+2>=n否则无右孩子。

储存

顺序存储

     顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。

     在物理上是数组,在逻辑上是二叉树。

b65175cb8a5b4059939239958657531d.png

链式储存

     链式结构存储就是用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。每个结点通常有三个域,数据域和左右指针域。

1e9fe6384d2a473b816acaac061d99cb.png

概念及结构

     堆是一种特殊的树形数据结构,通常表现为一棵完全二叉树,是用二叉树的顺序存储方式来存储元素的。

     堆分为小堆和大堆

小堆

     父结点小于子结点,但是父结点下面的两个子结点没大小区分。

90434b351ba54f5fbbdd3a7e9487de84.png

大堆

     父结点大于子结点,但是父结点下面的两个子结点没大小区分。

39670b21154e45ce9b4379c882f2c69d.jpg

建堆

     以下均为建小堆

向上调整建堆

     适用于一边插入一边建堆的情况。

     找到该孩子的父结点(利用上面性质5),在让父结点与它进行比较如果小于它则退出,如果大于则交换位置,重复上述操作直至循环结束或跳出循环。

void AdjustUp(int* arr, int child)
{int parent = (child - 1) / 2;while (child > 0){if (arr[child] < arr[parent])//将<改为>即建大堆{Swap(&arr[child], &arr[parent]);child = parent;parent = (child - 1) / 2;}elsebreak;}
}

     注:Swap是交换位置函数。

void Swap(int* p1, int* p2)
{int temp = *p1;*p1 = *p2;*p2 = temp;
}

向下调整建堆

     适用于对根节点进行调整。

     找到它的两孩子中小的那个,在让这个小的孩子与它进行比较如果孩子大于它则退出,如果小于则交换位置,重复上述操作直至循环结束或跳出循环。

void AdjustDown(int* arr, int n, int parent)
{int child = (parent * 2) + 1;while (child < n){if (child + 1 < n && arr[child + 1] < arr[child])//child + 1 < n防止非法访问,将后面的<改为>即建大堆{child++;}if (arr[parent] > arr[child])//将<改为>即建大堆{Swap(&arr[parent], &arr[child]);parent = child;child = (parent * 2) + 1;}elsebreak;}
}
//以上两个大小号均需要更改才能是建大堆

TOPK问题

     TOPK问题:即求数据结合中前K个最大的元素或者最小的元素。一般来说数据量比较大。

     如果有一个数组,数组里有N个数据,我们要找最大的前K个数据,要怎么做呢?

     找最大的前K个元素建大堆。

     找最小的前K个元素建小堆。

法一:

     先建一个大堆,然后让第一个结点的数据与最后一个结点交换,拿出最后的那个结点,然后再让根结点向下调整。重复上述操作K次。

void Heapsort(int* a, int n)
{int k = 0;scanf("%d", &k);for (int i = 0; i < n; i++){AdjustUp(a, i);}while (k--){Swap(&a[n - 1], &a[0]);AdjustDown(a, n - 1, 0);n--;}
}

     搞完后,数值大的数据都在数组的后面。我在这里没有拿出来。

法二:

     先建一个K个数据的小堆,然后让后面的N-K个数据跟该小堆的根结点进行比较,如果大于则进行交换,然后向下调整。最后拿出该堆即可。

void Heapsort(int* a, int n)
{int k = 0;scanf("%d", &k);for (int i = (k - 2) / 2; i >= 0; i--){AdjustDown(a, k, i);}for (int i = k; i < n; i++){if (a[i] > a[0]){Swap(&a[i], &a[0]);AdjustDown(a, k, 0);}}
}

     大家应该注意到了哈,这次建堆的方式有点不一样,这是先找到树的最后一个根结点(画四角星的是树的最后一个根结点)

ddab68e75d384c83aea977311d641089.jpg

然后向下调整建堆,然后遍历最后一个根结点之前的结点建堆。使用这种方式建堆会更方便时间复杂度为N,使用上面建堆方式时间复杂度是NlogN。

     总的来说法二要比法一要更优,因为当数据比较多时法一把所有的数据建堆就有点浪费时间了。

     在下篇中我会介绍二叉树的链式结构实现。

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

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

相关文章

解决word里加入mathtype公式后行间距变大

1.布局>页面设置>文档网格&#xff0c;网格栏选为无网格 2.固定间距

探索标准差与方差的奥秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、标准差与方差的基础理解 代码案例 二、标准差与方差的计算方法 方差的计算 标准差的…

QT——QSlider实现,QT滑动控件的使用

目录 简介滑动块调节两种方法滑动条触发信号量理想滑动块运用&#xff08;参考&#xff09; 简介 QT中滑动条的控件叫QSlider&#xff0c;继承自QAbstractSlider类。 主要用途是通过滑块的滑动的方式在一定范围内调节某个值。根据调节的后得到的结果去执行一些处理&#xff0c…

【AI基础】数据获取与整理、打标、增强方法、增强库imgaug

文章目录 常见的数据集网站爬虫工具使用搜索引起图片爬虫视频网站爬虫 数据整理数据检查和清洗数据去重数据集划分 数据标注数据标注工具 label studio 数据增强什么是数据增强单样本数据增强多样本数据增强样本生成方法数据增强imgaugimgaug 操作imgaug 使用 常见的数据集网站…

这款AI绘画软件,带你快速生成高质量产品效果图!

前言 随着人工智能技术的飞速发展&#xff0c;AI在设计领域的应用越来越广泛&#xff0c;。今天&#xff0c;介绍的一款能够自动生成高质量产品效果图的AI绘画软件——STARTAI。这款软件以其强大的功能和便捷的操作&#xff0c;正在重新定义电商产品效果图的制作流程。 AI局部…

RocketMQ .NET

RocketMQ 是一款由阿里巴巴集团开发并开源给Apache软件基金会的分布式消息及流处理平台。以其高吞吐量、低延迟、高可用性等特点而广受欢迎。支持Java&#xff0c;C, Python, Go, .NET等。 异步解耦&#xff1a;可以实现上游和下游业务系统的松耦合设计&#xff0c;使得服务部…

小红书图文笔记怎么做?纯干货!

小红书图文笔记的制作是一门艺术&#xff0c;它需要结合精美的图片和有价值的内容&#xff0c;以吸引和留住用户的注意力。伯乐网络传媒给大家分享制作小红书图文笔记的干货指南&#xff0c;包括准备、制作、发布和优化的各个环节。 一、准备阶段 确定目标受众&#xff1a;找到…

【NumPy】权威指南:使用NumPy的percentile函数进行百分位数计算

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

研学活动报名二维码怎么制作?

在组织研学活动时&#xff0c;老师们经常面临报名流程繁琐、信息收集不全面、统计工作耗时等问题&#xff1f;如何高效地管理学生的报名信息&#xff0c;确保活动顺利进行呢&#xff1f; 现在我们有了更多的选择。老师们可以快速制作出研学活动的研学活动报名二维码怎么制作&am…

DETR整体模型结构解析

DETR流程 Backbone用卷积神经网络抽特征。最后通过一层1*1卷积转化到d_model维度fm&#xff08;B,d_model,HW&#xff09;。 position embedding建立跟fm维度相同的位置编码(B&#xff0c;d_model,HW&#xff09;。 Transformer Encoder,V为fm&#xff0c;K&#xff0c;Q为fm…

非量表题如何进行信效度分析

效度是指设计的题确实在测量某个东西&#xff0c;一般问卷中使用到。如果是量表类的数据&#xff0c;其一般是用因子分析这种方法去验证效度水平&#xff0c;其可通过因子分析探究各测量量表的内部结构情况&#xff0c;分析因子分析得到的内部结构与自己预期的内部结构进行对比…

大模型预训练结果到底是什么?

近日参加一个线下 AI 交流会议&#xff0c;会上有个非本行业的老师提问&#xff1a;“大家说的训练好的大模型到底是什么&#xff1f;是像 Word 软件一样可以直接使用的程序吗&#xff1f;” 这个问题看似简单&#xff0c;却一下把我问住了。的确&#xff0c;我们这些身处 AI 领…

Kafka原生API使用Java代码-生产者-发送消息

文章目录 1、生产者发送消息1.1、使用EFAK创建主题my_topic31.2、根据kafka官网文档写代码1.3、pom.xml1.4、KafkaProducer1.java1.5、使用EFAK查看主题1.6、再次运行KafkaProducer1.java1.7、再次使用EFAK查看主题 1、生产者发送消息 1.1、使用EFAK创建主题my_topic3 1.2、根…

STM32 OTA需要注意问题

一、OTA设计思路&#xff08;问题&#xff09; 1、根据stm32f405 flash分布&#xff0c;最初将flash划分为四个区域&#xff0c;分别是Bootloader、APP1、APP2、参数区&#xff0c;设备上电后&#xff0c;进入Bootloader程序&#xff0c;判断OTA参数&#xff0c;根据参数来确定…

APP逆向之调试的开启

很基础的一个功能设置&#xff0c;大佬轻喷。 背景 在开始进行对APP逆向分析的时候&#xff0c;需要对APP打开调试模式。 打开调试的模式有多种方式可以通过直接改包方式也可以通过借助第三方工具进行打开调试模式。 下面就整理下这个打开调试模式的一些方式。 改包修改模…

Java面试题分享-敏感词替换 java 版本

入职啦最近更新了一些后端笔试、面试题目&#xff0c;大家看看能快速实现吗&#xff1f; 关注 入职啦 微信公众号&#xff0c;每日更新有用的知识&#xff0c;Python&#xff0c;Java&#xff0c;Golang&#xff0c;Rust&#xff0c;javascript 等语言都有 不要再用replaceAll做…

DNF手游攻略:开荒必备攻略!

DNF手游马上就要开服了&#xff0c;今天给大家带来最完整的DNF手游入门教程。这篇攻略主要讲述了 DNF手游开服第一天要注意的事项&#xff0c;这是一个新手必备的技能书&#xff0c;可以让你在开服的时候&#xff0c;少走一些弯路&#xff0c;让你更快完成任务&#xff01;废话…

蓝牙Mesh模块多跳大数据量高带宽传输数据方法

随着物联网技术的飞速发展&#xff0c;越来越多的设备需要实现互联互通。蓝牙Mesh网络作为一种低功耗、高覆盖、易于部署的无线通信技术&#xff0c;已经成为物联网领域中的关键技术之一。在蓝牙Mesh网络中&#xff0c;节点之间可以通过多个跳数进行通信&#xff0c;从而实现大…

【OrangePi AIpro】香橙派 AIpro 为AI而生

产品简介 OrangePi AIpro(8T)&#xff1a;定义边缘智能新纪元的全能开发板 在当今人工智能与物联网技术融合发展的浪潮中&#xff0c;OrangePi AIpro(8T)凭借其强大的硬件配置与全面的接口设计&#xff0c;正逐步成为开发者手中的创新利器。这款开发板不仅代表了香橙派与华为…

最新淘宝死店全自动采集私信筛选脚本,号称日赚500+【采集软件+使用教程】

原理&#xff1a; 利用脚本自动采集长时间未登录店铺&#xff0c;然后脚本自动私信对应的店铺&#xff0c;看看商家是不是不回消息来判断是否是死店&#xff0c;再下单购买死店的产品&#xff0c;超过48小时不发货就可以联系客服获得赔付&#xff0c;一单利润百分之5%-30%&…