二叉树的基础讲解

二叉树在遍历,查找,增删的效率上面都很高,是数据结构中很重要的,下面我们来基础的认识一下。(高级的本人还没学,下面的代码用伪代码或C语言写的)我会从树,树的一些专有名词,树的遍历,二叉树,二叉树的遍历以及后面升级的树进行一部分的介绍。

首先我们从最开始的树来进行讲解,我们知道链表是节点上一个连下一个形成一条长链,一个节点只能连接一个节点。而我们的树就是一个节点连接多个节点,就和我们生活中的树相似,一个点可以分出很多枝干。

下面就是开头节点连接四个节点的树,而树可以有很多的节点。

那么树的结构这么复杂多变,需要理清他们的结构关系。例如A我们要叫什么,H我们要叫什么?

树的相关专业名词

这里的名词是通过日常的树的一些名词和我们人与人之间关系组合形成的。所以结合这两部分可以更好记忆。我也会结合上面的这颗树来进行举例。

这里面打勾的是比较重要的。

节点✔

节点我们在链表里面就有讲过,不多说明。这里的A B C D E F G H都是节点

根节点

根节点就是树的起点节点这里的A就是根节点

双亲节点或父亲节点✔

一个节点的上一个节点就是他的父亲节点或双亲节点。例如A是B的父亲节点或双亲节点

孩子节点或子节点✔

一个节点的直接连接的下一个节点就是它的子节点或孩子节点例如B C D E都是A的孩子节点或子节点

节点的度

一个节点含有子树(或者可以说孩子节点)个数就是节点的度例如这里A的度是4,因为有B C D E四个树或者四个孩子节点。

树的度✔

根节点的度就是树的度例如上面的这颗树的度就是4。

非终端节点或分支节点

度不为零的节点,通俗说就是有孩子的节点这里除了F H D E都是分支节点。

兄弟节点

父亲节点是同一个的节点是兄弟节点,这里可以结合家庭关系理解并记忆。例如这里B C是兄弟,F G不是兄弟,但是是下面要说的堂兄弟节点。

节点的层次

就是节点在第几层,这里层次从上往下增长,一般定义根节点是第一层或者第零层。这里的B是第二层或者第一层(分别对应根节点的第一层和第零层)。

树的高度或深度✔

树的最大层次。如图的最大层次是4。

堂兄弟节点

双亲在同一层的节点互为堂兄弟。例如F G就是堂兄弟。

节点的祖先

从根到该节点所经分支上的所有节点。例如A是所有节点的祖先

子孙

以某节点为根的子树中任一节点都称为该节点的子孙。上如除了A的节点都是A的子孙。

森林

由m(m>0)棵互不相交的树的集合称为森林。

多叉树的遍历

因为树的节点个数不缺定,所以我们要借助其他的数据结构来存储我们一个节点的子节点。

例如我们要遍历上图的A,我们先遍历A里面的内容,然后再将A的所有节点写进栈里面,或者队列里面,然后我们进行循环,如果栈或者队列为空我们就停止循环。每次出数据的时候我们就将它的子节点全部存进这个数据结构里。这样我们就可以完成所有节点的遍历。

伪代码如此,我不会写伪代码,大概看看吧。

第二种是比较厉害的处理办法,不需要运用的任何数据结构,但是树的创建结构需要改变一下

我们将上面的树结构改成这样,我们增强层之间的联系,而亲子之间只让两个之间有联系。这样遍历的顺序就是A->B里面所有节点->C里面所有节点->D里面所有节点->E里面所有节点。这个需要用到递归来处理。这里我用C语言来写一下

首先是树的定义和树的创建,结构和上面图是一样的:

这里结构体的创建孩子的节点决定于所有节点中节点最大孩子数。

然后是遍历函数和main函数

结果也是对的

树的运用

像我们电脑、手机里面的文件夹就是一个多叉树,一个文件夹就相当于一个节点,文件夹里面的内容就是子文件夹

二叉树

二叉树是树里面特殊的一种树,每个节点的孩子节点<=2。二叉树因为只分了左右节点可以很好的控制数据关系,更好的进行相关的数据操作。

下面就是二叉树的一些主要出现的操作,如果能自主写的到这些,那么二叉树的基础部分掌握的相对牢固:

二叉树的三种特殊情况

满二叉树

设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个树,第 h 层所有的结点都连续集中在最左边,而满二叉树是完全二叉树的一种

完全二叉树

深度为k且有2^k-1个结点的二叉树

平衡二叉树

 1,左子树与右子树的高度之差的绝对值小于等于1;

 2,左子树和右子树也是平衡二叉树.

二叉树里面的恒等式

1,叶子节点数=度为2的节点的个数+1

二叉树的遍历

二叉树的遍历是认识二叉树最重要的一点,或许大家在大学里面学习了二叉树的遍历——前中后序遍历,但是大多数人是没有真正了解三个序具体过程是怎么来的。

二叉树因为涉及多叉也是要用递归来遍历的,或者用数据结构进行存储。

我们一下面这颗二叉树来进行分析三个序。

这颗树的手工创建代码如下

前序

前序遍历遵从的是先遍历节点的内容,再遍历节点的左子树,在遍历节点的右子树。

下面进行分析:

首先声明:这颗树有点大,如果下面的分析看不懂可以先从黑体字开始看,就是A左子树B的遍历。

要遍历这颗二叉树,先要遍历A节点,那么先遍历A节点的值是'A',然后遍历A的左子树B。遍历B先遍历它的值是'B',然后遍历B的左子树D,遍历D先遍历值'D',然后遍历D的左子树G,遍历G先遍历它的值'G',然后遍历G的左子树,G的左子树是NULL,所以为空,再遍历G的右子树也是空的。G遍历完了,标志D的左子树遍历完了,我们要遍历D的右子树,右子树为NULL,D遍历完,标志B的左子树遍历完了。现在要遍历B的右子树E,欲遍历E要遍历E的值'E',然后遍历E的左子树H,要遍历H先遍历H的值然后依次遍历左右子树都为空,那么E的左子树遍历完了遍历E的右子树I,I也是同样操作,欲遍历I先遍历I的值'I',然后遍历I的左子和右子树都为空,遍历完标志E的右子树遍历完了,就标志B的右子树遍历完了,即B树遍历完了,就标志A的左子树遍历完了。然后就要遍历A的右子树,先遍历C,先遍历C的值'C',然后遍历C的左子树为空,然后遍历C的右子树F,先遍历F的值'F',然后遍历F的左子树J,先遍历J的值'J',然后遍历J左右子树都为空,然后遍历F右子树K,先遍历K的值'K',然后遍历K的左右子树都是空,然后F遍历完,标志C的右子树遍历玩标志A的右子树遍历完。最后标志这颗树遍历完。

最终的遍历顺序是A->B->D->G->NULL->NULL->NULL->E->H->NULL->NULL->I->NULL->NULL->C->NULL->F->J->NULL->NULL->K->NULL->NULL

而我现在写的过程也是递归调用的全过程。

那么我们开始写它的递归代码:

就是这么简单,其实打印NULL的代码也不需要,但这里主要是看遍历的流程。函数的递归流程是和上面流程一模一样的。

我们也可以看到程序遍历的和我们分析出来的是一样的。

中序

中序是先遍历左子树,再遍历节点数据,再遍历右子树。

只要把前序看懂了,中序就是水到渠成的事。

依然是上面的这张图,我们再分析一下。这次我只分析A的左子树B:

要遍历B,先遍历B的左子树D,要遍历D先遍历左子树G,要遍历G先遍历G左子树为空,然后遍历G值,然后遍历G右子树,G遍历完了标志D左子树遍历完了,然后遍历D值,然后遍历D右子树为空,然后D树遍历完标志B的左子树遍历完,然后遍历B值,然后遍历B的右子树E,先遍历E的左子树H,先遍历H左子树为空,然后遍历H值,然后遍历H的右子树为空,然后H遍历完标志E的左子树遍历完了,然后遍历E值,然后E的右子树I,先遍历I左子树为空,然后遍历I值,然后遍历右子树为空,然后标志E遍历完,标志B右子树遍历完,标志B树遍历完。

A的右树你们自己来试一试,最后结果是:

NULL->G->NULL->D->NULL->B->NULL->H->NULL->E->NULL->I->NULL->A->NULL->C->NULL->J->NULL->F->NULL->K->NULL

写代码也很好写,交换一下位置就行了

后序

先遍历节点左子树,然后遍历节点右子树,然后是遍历节点的值。

后序我不会说过程了,请大家自己尝试。

答案是

NULL->NULL->G->NULL->D->NULL->NULL->H->NULL->NULL->I->E->B->NULL->NULL->NULL->J->NULL->NULL->K->F->C->A

然后是代码和运行结果:

下面我再出几个题

答案:

前:A B NULL E H NULL NULL I NULL NULL C NULL F J NULL NULL K NULL NULL

中:NULL B NULL H NULL E NULL I NULL A NULL C NULL J NULL F NULL K NULL

后:NULL NULL NULL H NULL NULL I E B NULL NULL NULL J NULL NULL K F C A

答案:

前:A B D G NULL NULL I NULL NULL NULL C H NULL NULL F J NULL NULL K NULL NULL

中:NULL G NULL D NULL I NULL B NULL A NULL H NULL C NULL J NULL F NULL K NULL

后:NULL NULL G NULL NULL I D NULL B NULL NULL H NULL NULL J NULL NULL K F C A

模拟前序(深搜)

我们在树的遍历就说到用数据结构存储节点,这里我们就来用栈来实现实现。

栈的函数就自己写或者CV一下,不会的可以看我的相关博客。

(忘记栈的销毁了,记得销毁,养成习惯)

层序(广搜)

层序就是一层一层遍历,就是按顺序遍历,那么这个按顺序我们就想到了队列。

层序我们发现了一个规律,它遍历出来的数据是一层一层从上到下从左到右遍历的,数据提现的很直观,我们可以通过结果很轻松的知道二叉树大概长什么样子,但是可能底层的数据不准确。但是完全二叉树就是一个例外,如果告诉了是完全二叉树,又告诉了它层序的结果,那么这颗树就已知了。而这个和我们堆的结构是密切相关的。

(忘记队列的销毁了,记得销毁,养成习惯)

二叉树的其他函数

这些函数也是需要会写的

这里面有几个已经写了就不写了

首先是二叉树的构建

二叉树销毁


二叉树节点个数


二叉树叶子节点个数


二叉树第k层节点个数


二叉树查找值为x的节点


判断二叉树是否是完全二叉树

这个需要讲一下,完全二叉树是最后一个层序值前面都不能有NUL,当出现NULL看后面还有没有NULL就行了.

普通二叉树的缺陷

我们创造二叉树最后是为了查找快速,二叉树的查找是类似于二分的,时间复杂度是logN,速度非常快。但是如果我们二叉树建立的比较特殊,所有的节点都是在上一个节点的做子树上,将会变成一条链表,时间复杂度也降为N。所以会有更高级的二叉树来弥补这个缺陷。

高级数据结构里面的树

据我现在了解后面会有平衡二叉树(AVL树),红黑树(二叉树),B树,B+树(多叉)等树。这些树我也不知道长什么样,但是可以时刻保持logN的时间复杂度。

另外这些高阶树会和哈西表进行结合,将红黑树挂到哈西表的每个格子上,让时间复杂度进一步减小。总之学习数据结构的道路还很漫长.......

求赞和关注

都看到这里了,求大家点赞关注一下吧😊

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【博客719】时序数据库基石:LSM Tree的增删查改

时序数据库基石&#xff1a;LSM Tree的增删查改 LSM结构 LSM树将任何的对数据操作都转化为对内存中的Memtable的一次插入。Memtable可以使用任意内存数据结构&#xff0c;如HashTable&#xff0c;BTree&#xff0c;SkipList等。对于有事务控制需要的存储系统&#xff0c;需要在…

web安全渗透测试十大常规项(一):web渗透测试之JAVA反序列化

渗透测试之PHP反序列化 1. Java反序列化1.1 Java安全-反序列化-原生序列化类函数1.1.1 原生序列化类函数:1.2 Java安全-SpringBoot框架-泄漏&CVE1. Java反序列化 1、序列化与反序列化 序列化:将内存中的对象压缩成字节流 反序列化:将字节流转化成内存中的对象2、为什么…

huggingface官网下载并处理ImageNet2012数据集

文章目录 一、下载imagenet2012数据集二、转换imagenet数据集格式 ImageNet数据集可以直接从ImageNet官方网站获取数据&#xff0c;但通常需要注册并遵守使用协议。另外&#xff0c;由于数据集较大&#xff0c;往往下载需要花费大量的时间空间&#xff0c;而通过huggingface下载…

达梦8 通过SF_INJECT_HINT解决新排序机制下失控语句影响其他SQL执行的问题

达梦数据库有两种排序机制。当SORT_FLAG设置0时&#xff0c;采用旧排序机制&#xff1b;当SORT_FLAG1时&#xff0c;采用新排序机制。详见《达梦新老排序机制的对比》 两种排序机制各有优缺点。 新排序机制引入了全局排序区概念&#xff0c;虽然避免了内存溢出导致系统OOM&am…

[数据概念|方案实操]清华数据大讲堂5-数据要素化治理的理论方法与工程实践

“ 数据要素化是资产化的重要前提和实现路径” 鼹鼠哥公众号链接在 [数据概念|方案实操]清华数据大讲堂5-数据要素化治理的理论方法与工程实践 (qq.com) 2024年6月5日&#xff0c;清华数据大讲堂第五讲开讲。 中国电子信息产业集团副总 陆志鹏 以《数据要素化治理的理论方法与…

扎克伯格2017年哈佛大学毕业典礼演讲:Mark Zuckerberg Harvard Commencement 2017

Facebook Founder Mark Zuckerberg Commencement Address | Harvard Commencement 2017 Link: https://www.youtube.com/watch?vBmYv8XGl-YU 文章目录 Facebook Founder Mark Zuckerberg Commencement Address | Harvard Commencement 2017SummarySummary of Mark Zuckerberg…

[图解]建模相关的基础知识-16

1 00:00:00,350 --> 00:00:04,130 刚才那个&#xff0c;就相当于&#xff0c;12这个我们可以认为是什么 2 00:00:05,020 --> 00:00:11,360 我们用类图来表达就是&#xff0c;员工、电话 3 00:00:13,320 --> 00:00:15,080 多个 4 00:00:15,090 --> 00:00:16,440 …

MySQL 超出月份最大日期(工作总结)

前几天帮同事修改了一个bug&#xff0c;这个bug是怎么造成的呢。先来看需求&#xff0c;系统需要统计某个月份的数据。很简单的一个需求。 同事的写的MySQL语句 SELECTREPLACE(FORMAT(sum(count_value),2), ,, ) as value,<if test"type day">count_date as…

068、PyCharm 关于Live Template模板

在 PyCharm 编辑器中&#xff0c;Live Templates 是一种功能强大的工具&#xff0c;可以帮助我们快速插入常用的代码片段或模板。 以下是在 PyCharm 中添加 Live Templates 的步骤&#xff1a; 添加 Live Templates 步骤&#xff1a; 打开 PyCharm 编辑器。 转到菜单栏中的 …

分布式,容错:10台电脑坏了2台

由10台电脑组成的分布式系统&#xff0c;随机、任意坏了2台&#xff0c;剩下的8台电脑仍然储存着全部信息&#xff0c;可以继续服务。这是怎么做到的&#xff1f; 设N台电脑&#xff0c;坏了H台&#xff0c;要保证上述性质&#xff0c;需要有冗余&#xff0c;总的存储量降低为…

三、MyBatis实践:提高持久层数据处理效率

三、MyBatis实践&#xff1a;提高持久层数据处理效率 目录 一、Mybatis简介 1.1 简介1.2 持久层框架对比1.3 快速入门&#xff08;基于Mybatis3方式&#xff09; 二、MyBatis基本使用 2.1 向SQL语句传参 2.1.1 mybatis日志输出配置2.1.2 #{}形式2.1.3 ${}形式 2.2 数据输入 2…

redis主从复制、哨兵、集群

在实际的生活环境中&#xff0c;如果只使用一个redis进行读写操作&#xff0c;那么面对庞大的访问人群是崩溃的&#xff0c;所以可以有几个redis&#xff0c;一个用来做主机&#xff0c;提供修改数据操作&#xff0c;而这个主机用来控制其他redis&#xff0c;即将更新的发送&am…

【七】【QT开发应用】跨UI发送信号,跨线程发送信号

跨UI发送信号 基本框架 新建窗口 自定义信号 跨线程发送信号 新建线程 查看线程号 完整代码 跨UI发送信号 setdialog.h #ifndef SETDIALOG_H #define SETDIALOG_H#include <QDialog>namespace Ui { class setdialog; }class setdialog : public QDialog {Q_OBJECTpub…

【Python】已解决:ModuleNotFoundError: No module named ‘paddle’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘paddle’ 一、分析问题背景 在Python编程中&#xff0c;ModuleNotFoundError是一个常见的错误&#xff0c;它通常发生…

C语言的数据结构:树与二叉树(树篇)

前言 之前所学到的数据结构都是线性结构特征&#xff0c;所谓线性就是在结构上&#xff0c;将节点连接起来时&#xff0c;像一条线一样。如链表则是上一个节点包含下一个节点地址的指针&#xff0c;这样依次下去。而串、队列、栈则实现方式都依赖于链表或顺序表而实现&#xf…

Inception_V2_V3

Inception_V2_V3 CNN卷积网络的发展史 1. LetNet5(1998) 2. AlexNet(2012) 3. ZFNet(2013) 4. VGGNet(2014) 5. GoogLeNet(2014) 6. ResNet(2015) 7. DenseNet(2017) 8. EfficientNet(2019) 9. Vision Transformers(2020) 10. 自适应卷积网络(2021) 上面列出了发展到现在CNN的…

智能优化算法改进策略之局部搜索算子(三)—二次插值法

1、原理介绍 多项式是逼近函数的一种常用工具。在寻求函数极小点的区间&#xff08;即寻查区间&#xff09;上&#xff0c;我们可以利用在若干点处的函数值来构成低次插值多项式&#xff0c;用它作为求极小点的函数的近似表达式&#xff0c;并用这个多项式的极小点作为原函数极…

示例:推荐一个基于第三方开源控件库DataGridFilter封装的FilterColumnDataGrid,可以像Excel拥有列头筛选器

一、目的&#xff1a;基于第三方开源控件库DataGridFilter封装的FilterColumnDataGrid&#xff0c;可以像Excel拥有列头筛选器&#xff0c;感兴趣的可以去下方链接地址查看开源控件库地址。本控件封装的目的在于将第三方库的皮肤和样式封装到皮肤库中可统一设置样式&#xff0c…

Day 31:100334. 包含所有1的最小矩形面积Ⅰ

Leetcode 100334. 包含所有1的最小矩形面积Ⅰ 给你一个二维 **二进制 **数组 grid。请你找出一个边在水平方向和竖直方向上、面积 最小 的矩形&#xff0c;并且满足 grid 中所有的 1 都在矩形的内部。 返回这个矩形可能的 **最小 **面积。 确定首次出现 1 的第一行 top&#xf…

转让神州开头的无区域科技公司需要多少钱

您好&#xff0c;我公司现有2家无区域神州名称的公司转让。所谓无区域名称是公司名称中不带有行政区划、及行业特点的公司名称&#xff0c;都是需要在工商总,局核准名称的&#xff0c;对于民营企业来说也比较喜欢这种名称名称很大气&#xff0c;现在重核更严格了&#xff0c;所…