【数据结构之二叉树系列】二叉树的基本知识

news2024/9/24 1:16:20

目录

    • 前言
    • 一、树
        • 1、树的相关概念
          • (1)结点
          • (2)结点的度
          • (3)叶结点
          • (4)分支结点
          • (5)父亲结点
          • (6)子节点
          • (7)树的度
          • (8)结点的层次
          • (9)树的深度(高度)
          • (10)结点的祖先
          • (11)子树
        • 2、树的表示方法
    • 二、二叉树
        • 1、特殊的二叉树
          • (1)满二叉树
          • (2)完全二叉树
    • 三、二叉树的一些重要性质
    • 四、二叉树的一些常见题目

前言

前面我们学习的都是一些线性的数据结构,比顺序表,链表,栈和队列,逻辑结构比较简单,今天我们重点学习的是一种非线性的数据结构,就是树形结构。

一、树

在现实生活中我们都看到过树,如下图,所以对树的形状会有一个基本的认知
在这里插入图片描述
但是在数据结构这门课中我们学习的树可就不是长上面这个样子了,而是下面这个奇怪的样子:
在这里插入图片描述
在这里插入图片描述

1、树的相关概念

(1)结点

每一个树都是由一个个小小的单元组成,在数据结构中,我们将这样的小单元称为结点。
在这里插入图片描述
像上面ABCDEF都是这棵树的结点。

(2)结点的度

每一个结点都是相当于一棵子树的根,而根又会有很多的分支,在数据结构中,一个结点有多少个分支,我们就说这个结点的度为多少。比如:
在这里插入图片描述
像上面这个图中,A这个结点有三个分支,就说明A的度为3。E和F这两个结点没有分支,我们就说这两个结点的度为0。

(3)叶结点

我们将度为0的结点称为叶子结点,或简称为叶节点。如下图中的EF结点度为0,所以它们为叶节点。
在这里插入图片描述

(4)分支结点

与叶子结点相反,度不为0的结点我们称为分支结点,如下图中AC结点的度不为0,所以AC结点为分支结点。
在这里插入图片描述

(5)父亲结点

如果一个结点含有分支,也就是包含子树,则我们将这个结点称为其子树的父亲结点或双亲结点,后面我们是用parent来表示。如下图中的A结点有三个分支BCD结点,所以我们成A结点是BCD结点的父亲结点。
在这里插入图片描述

(6)子节点

一个结点含有的子树的根结点我们称为这个结点的子节点,就是我们要知道一个子树是由自己的根节点和另外的子树构成的。下图中:A包含BCD三个子树,BCD三个结点分别为对应子树的根节点,所以我们成BCD结点为A结点的子节点,后面我们是用child来表示。
在这里插入图片描述

(7)树的度

一棵树中所有结点中度最大的结点的度我们称为这棵树的度,下图中:显然A结点的度最大,是3,所以我们说这棵树的度为3。
在这里插入图片描述

(8)结点的层次

从这棵树的根节点开始定义,我们说根结点是第一层,其子树的根节点为第三层,以此类推。下图中:A为第一层,BCD为第二层,EF为第三层。
在这里插入图片描述

(9)树的深度(高度)

一棵树最大的层次就是这棵树的深度(高度),如下图中:这棵树的最大层次为3,所以我们说这棵树的深度(高度)为3。
在这里插入图片描述

(10)结点的祖先

从根到该节点所经分支上的所有结点都称为该节点的祖先,注:在OJ题中一个结点也可以算成其自己的祖先。如下图中:从A到E,经历了ACE,所以我们成ACE结点都是E结点的祖先。
在这里插入图片描述

(11)子树

任意一个结点都可以说是由根节点和其自己的子树组成

2、树的表示方法

上面介绍的树是树中的一种特殊的结构,二叉树,二叉树中每个节点的度最大为2,但是树就不一样了,树中的每一个结点的度是不确定的,可多可少。所以表示起来会比较麻烦,在这里我们学习一种比较优秀的表示方法:孩子兄弟表示法,这个方法需要和前面学习的链表结合起来,首先需要定义树中结点的结构

// 定义树存储的数据类型
typedef int TreeDataType;

// 定义一棵树的结点的结构
struct TreeNode
{
	TreeDataType data;
	struct TreeNode* first_child;
	struct TreeNode* next_brother;
};

其中data表示结点存储的值,first_child指向的是该节点的第一个孩子,next_brother指向的是该节点向右的下一个结点,我们称为兄弟结点。如下图:
在这里插入图片描述

二、二叉树

一棵树中,如果每一个结点的度都不超过2,则称这棵树为二叉树。二叉树中的孩子结点是有左右之分的,位于左边的结点称为左孩子结点,位于右边的结点称为右孩子结点,子树同样也有左右之分,位于左边的称为左子树,位于右边的称为右子树。
在这里插入图片描述

1、特殊的二叉树

(1)满二叉树

如果每一层的结点都达到最大值,则我们称这棵树为满二叉树,如:一棵树中,第一层是根节点,最多只有一个结点,第二层最大有两个结点,第三层最多有四个结点,第四层最多有8个结点,以此类推,第N层最多有2^(N-1)个结点,如下图就是一棵满二叉树。
在这里插入图片描述
在这里插入图片描述

(2)完全二叉树

满二叉树是一种特殊的完全二叉树,完全二叉树的特点是:如果这棵树有N层,前N-1层的结点树都是达到对应层的最大值,最后一层可能达到最大,也可能未达到最大,但是从左到右是满的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、二叉树的一些重要性质

  1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1)个结点,如果这棵树是满二叉树,那么此时每一层的结点的数量都会满足以上的性质
  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点树为2^h -1,如果这个树是满二叉树,那么此时这个数的结点数就是达到最大值,为2^h -1,这个结论是根据等比数列的求和公式计算得出的
  3. 对于任何的一棵二叉树,如果度为0的结点的个数为n0,度为2的结点个数为n2,那么此时会满足:n0 = n2+1,通常情况下,要注意题目是否给出一个条件是完全二叉树,如果题目说这棵树是一棵完全二叉树,那么此时可以知道,树中度为1的结点个数可能为0或者1,当树中存在的根节点只存在左子树时,那么这种情况下,度为1的结点数为1,当树中不存在这样的子树时,也就是树中的每一个子树都是同时存在左右子树的,那么此时树中度为1的结点数为0。
  4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度为h = log2(n+1),这个结论是由第2个性质推出来的
  5. 对于具有n个结点的完全二叉树,如果按照从上至下从左到右的数组顺序对所有结点从0开始编号,则对序号为i的结点有:
  • i>0,i位置的结点存在双亲结点,序号为:(i-1)/2,若i = 0,则说明此时该节点为该树的根节点,不存在双亲结点
  • 2*i+1<n,则说明该结点存在左子树,左子树的根节点序号为:2*i+12*i+1>=n,则说明该结点不存在左子树
  • 2*i+2<n,则说明该结点存在右子树,右子树的根节点序号为:2*i+22*i+2>=n,则说明该结点不存在右子树

四、二叉树的一些常见题目

  1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( )
    A 不存在这样的二叉树
    B 200
    C 198
    D 199

解:根据二叉树的性质,度为0的结点数比度为2的结点数多1可得答案。

2.下列数据结构中,不适合采用顺序存储结构的是( )
A 非完全二叉树
B 堆
C 队列
D 栈

解:非完全二叉树由于其中可能存在只有右子树的情况,所以如果将非完全二叉树中的结点存在于数组中,那么就可能出现内存空间浪费的现象,因此,非完全二叉树不适合顺序存储。堆的本质就是完全二叉树,其中的结点适合存在数组中按下标进行编号,不会出现空间浪费。队列和栈在前面学习过,都是经典的线性结构,适合存在于数组中。

3.在具有 2n 个结点的完全二叉树中,叶子结点个数为( )
A n
B n+1
C n-1
D n/2

解:假设树中叶子结点的个数为x,则度为2的结点个数为x-1,要注意题目中的一个隐含的条件,就是完全二叉树,这个条件告诉我们,树中度为1的结点的数量可能为1或者0,所以我们需要进行分类讨论:
当树中的度为1的结点数为1时:x + x-1 +1 = 2n,即2x = 2n,x = n,此时叶子结点的个数为n
当树中的度为1的结点数为1时:x + x-1 = 2n,即2x = 2n+1,x = n+1/2,显然不符合条件 综上,叶子结点的个数为n

4.一棵完全二叉树的节点数位531个,那么这棵树的高度为( )
A 11
B 10
C 8
D 12

解:这道题告诉了我们树的总结点数,所以我们需要想性质,二叉树的最大结点数量为:2^h -1,假设该树的深度为10,则最大结点数位:2^10 -1,就是1023,当该树的深度为9时,最大结点数为:511<523,显然不符合题意,所以该树的深度为10,前9层是满的,最后一层不满


5.一个具有767个节点的完全二叉树,其叶子节点个数为()
A 383
B 384
C 385
D 386

解:解法与第3题一样

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

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

相关文章

Java标准输入输出流(in/out)

文章目录前言标准输入流标准输出流前言 Java通过系统类System实现标准输入/输出的功能&#xff0c;在Java中输入输出数据一般&#xff08;图形化界面例外&#xff09;要用到标准输入输出流 System.in 标准输入&#xff1a;通常指从键盘输入数据System.out 标准输出&#xff1…

VueJs中如何使用Teleport组件

前言在DOM结构相对比较复杂,层级嵌套比较深的组件内,需要根据相对应的模块业务处理一些逻辑,该逻辑属于当前组件但是从整个页面应用的视图上看,它在DOM中应该被渲染在整个vue应用外部的其他地方,不能影响组件的结构比较常见的应用场景:就是全屏的模态框,控制元素的位置,也是可以…

分享124个ASP源码,总有一款适合您

ASP源码 分享124个ASP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 124个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/1MLzeod5DblXbW3sZAeTsEQ?pwd9jfe ​​​​​​​…

连续系统的数字PID控制仿真-2

被控对象为三阶传递函数&#xff0c;采用Simulink模块与M函数相结合的形式&#xff0c;利用ODE45的方法求解连续对象方程&#xff0c;主程序由Simulink模块实现&#xff0c;控制器由M函数实现。输入指令信号为正弦信号0.05sin(2Tt)。采用PID方法设计控制器&#xff0c;其中kp …

casbin权限和配置文件的理解

官方文档 基础权限模型 下图为我基于个人理解画出来的(关于多租户RBAC模型可能有误) 发现一篇博客讲的还行Casbin权限模型&#xff0c;看他的权限系统设计模型分析部分 casbin配置文件内容的结构解释 注意matchers可以设置多个。我在知道这个之前一直疑惑为什么需要policy_…

【设计模式】我终于读懂了外观模式。。。

今天是正月初二&#xff0c;在这里给大家拜年啦&#xff01; 祝愿大家&#xff1a;兔年大吉大利&#xff0c;兔年顺顺利利&#xff0c;兔年快快乐乐&#xff0c;兔气十足十足&#xff0c;兔年富富满堂&#xff0c;兔年财源广进&#xff0c;兔年步步高升&#xff0c;兔年梦想成真…

【大数据hive】hive ddl语法使用详解

一、前言 DDL&#xff0c;也叫数据定义语言 (Data Definition Language, DDL)&#xff0c;是SQL语言集中对数据库内部的对象结构进行创建&#xff0c;删除&#xff0c;修改等的操作语言&#xff0c;这些数据库对象包括database、table等&#xff0c;使用过mysql的同学应该对此很…

抗积分饱和PID控制算法及仿真

积分饱和现象所谓积分饱和现象是指若系统存在一个方向的偏差&#xff0c;PID 控制器的输出由于积分作用的不断累加而加大&#xff0c;从而导致执行机构达到极限位置Xmax(例如阀门开度达到最大)&#xff0c;如图所示&#xff0c;若控制器输出u(k)继续增大&#xff0c;阀门开度不…

STL - 常用算法

常用遍历算法 for_each #include <algorithm> #include <functional> #include <iostream> #include <vector>using namespace std;//常用遍历算法 - for_each//普通函数 void print01(int val) {cout << val << " "; } //仿函数…

【每日一题Day95】LC1815得到新鲜甜甜圈的最多组数 | 状态压缩dp 记忆化搜索

得到新鲜甜甜圈的最多组数【LC1815】 有一个甜甜圈商店&#xff0c;每批次都烤 batchSize 个甜甜圈。这个店铺有个规则&#xff0c;就是在烤一批新的甜甜圈时&#xff0c;之前 所有 甜甜圈都必须已经全部销售完毕。给你一个整数 batchSize 和一个整数数组 groups &#xff0c;数…

LeetCode刷题模版:187-189、198-200

目录 简介187. 重复的DNA序列188. 买卖股票的最佳时机 IV【未理解】189. 轮转数组198. 打家劫舍199. 二叉树的右视图200. 岛屿数量结语简介 Hello! 非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出~ ଘ(੭ˊᵕˋ)੭ 昵称:海轰 标签:程序猿|C++选手|学生 简…

【论文翻译】Attention Is All You Need

【论文】Attention is All you Need (neurips.cc) 摘要 主要的序列转换模型是基于复杂的循环或卷积神经网络&#xff0c;其中包括一个编码器和一个解码器。表现最好的模型还通过注意机制连接编码器和解码器。我们提出了一个新的简单的网络架构&#xff0c;Transformer&#xf…

线程常用方法及常见状态

终止线程应该怎么终止一个线程呢&#xff1f;当线程完成任务时。通过使用变量来控制run方法退出的方式停止线程&#xff0c;即通知方式。这里详细介绍一下2的方式。在A线程依靠变量循环跑的过程ing&#xff0c;主线程通过修改A线程的变量&#xff0c;来控制线程终止。为A线程中…

SpringBoot配置文件详解

简介 SpringBoot全局配置文件默认为src/main/resources下的application.properties&#xff0c;后缀可以改为yml&#xff0c; 如果application.yml和application.properties两个配置文件都存在&#xff0c;那么&#xff0c;properties优先级更高 官网(Spring Boot 全部配置项)&…

01_kobject和ktype创建设备文件和设备目录

总结:创建设备文件的方法 设备文件属性指的是 /sys/yyy/xxx yyy:代表这个设备的目录 xxx:代表这个驱动设备的各种属性,我们可以直接操控属性来控制这个设备 比如之前常见的 echo 5 > /sys/led/brightness 直接操作这个属性来更改led的亮度 1 创建设备kobj对象,绑定目录 k…

C语言中不定参数 ... 的语法、函数封装

文章目录Intro语法测试依赖库新函数使用测试&#xff1a;遍历并打印不定参数中的值用两种方式封装函数&#xff1a;对多个int值求和总结Intro 有一天看C代码看到某个方法有这样的定义&#xff1a;在函数形参列表处&#xff0c;有...的写法&#xff0c;就像Java中的不定参数那样…

JDK8 新特性之Stream流方法详解

目录 一&#xff1a;集合处理数据的弊端 二&#xff1a;Stream流式思想概述 小结 &#xff1a; 三&#xff1a;获取Stream流的两种方式 方式1 : 根据Collection获取流 方式2 : Stream中的静态方法of获取流 小结 四&#xff1a;Stream常用方法和注意事项 Stream常用方法…

19. 函数基础知识详解

1. 什么是函数 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段。函数能提高应用的模块性&#xff0c;和代码的重复利用率。之前文章中我们已经使用过python提供的内建函数&#xff0c;比如print()。但你也可以自己创建函数…

【JUC并发编程】线程池及相关面试题 详解

【JUC并发编程】线程池及相关面试题 详解 参考资料&#xff1a; 第十二章 线程池原理 深入浅出Java多线程原理 两道面试题&#xff0c;深入线程池&#xff0c;连环17问 深入理解Java并发编程之线程池、工作原理、复用原理及源码分析 硬核干货&#xff1a;4W字从源码上分析JUC…

Java二叉树OJ题

目录1. 检查两颗树是否相同2. 另一颗树的子树3. 翻转二叉树4. 判断一颗二叉树是否是平衡二叉树4.1 时间复杂度为O(n*n)【从上而下递归】4.2 时间复杂度为O(n)【从下而上递归】5. 对称二叉树6. 二叉树的构建及遍历7. 二叉树创建字符串8. 两个指定节点的最近公共祖先8.1 指定结点…