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

数据结构:二叉树概念篇(算法基础)

目录

一.有向树的图论基础

1.有向树的相关基本概念

有向树的基本定义:

有向树的结点的度:

有向树的度:

有向树的根结点,分枝结点,叶结点: 

树的子树:

树结点的层次:

树的高度:

2.一个基本的数学结论

3.有序有向树

二.数据结构中树的顺序存储结构与链式存储结构

1.数据结构的物理结构与逻辑结构

2.物理结构为顺序表(数组)的树形数据结构

3. 物理结构为链表的树形数据结构

三.二叉树

1.二叉树基本概念 

2.两个重要的特殊二叉树

3. 关于二叉树的一些常用数学结论

(1).第一组结论 

(2).第二组结论(数组实现二叉树的算法基础)


一.有向树的图论基础

基本引理:如果图G(结点数大于等于2)中不存在回路,则至少有一个结点的度为1 

本篇所讨论的树都是有向树 

1.有向树的相关基本概念

  • 有向树的基本定义:

设T是由有限个结点构成有向简单连通图,且T的无向底图不存在任何回路,则称T为有向树:

  • 有向树的结点的度:

 结点的入度:现有树结点A,以A为终点的有向边的条数称为结点A的入度:

结点的出度: 现有树结点A,以A为起点的有向边的条数称为结点A的出度:

以结点A为终点的有向边的另一端的结点称为A的父结点(parent)

以结点A为起点的有向边的另一端的结点称为A的孩子结点(child)

  •  有向树的度:

有向树的度 = 该树所有结点的出度中的最大值:

  • 有向树的根结点,分枝结点,叶结点: 

  1. 根结点的入度为0
  2. 叶结点的出度为0
  3. 其余入度和出度均不为0的结点称为树的分枝结点  
  •  树的子树:

将一个有向树T的根结点去掉,该树则会被分成若干个互不连通的子树,如图:

上图中T的子树t1,t2,t3都可以再以相同的方式被划分成更小的子树直到树图被划分为若干树叶.

注意:在仅有一个根结点的树形结构中子树之间没有通路(不然图中会出现回路)

  • 树结点的层次:

从根结点开始算起沿着有向边进行遍历,根结点某一个特定结点所遍历的结点个数称为某特定结点的层次

  1.  层次相同父结点相同的结点互为兄弟结点(比如上图中的E和F)
  2.  层次相同父结点不同的结点互为堂兄弟结点(比如上图中的F和G)
  • 树的高度:

树的所有结点的层次中的最大值称为该树的高度:比如上图中的树的高度为4

2.一个基本的数学结论

  • 关于树的一个基本命题:若树有n个结点,m条有向边,则m=n-1;

该性质可以通过数学归纳法进行证明:

  1. 显然n=1时,则m=0,m=n-1成立;
  2. 假设n=k(k>=1)时命题成立,任意具有k个结点的树都有k-1条边
  3. 设树G有n=k+1个结点时(k>=1)边数为m。 由于G中没有回路,根据基本引理G中必然存在度(出度+入度)为1的结点,设这个结点为u。 从G中删去结点u(相当于同时删去了一条边和一个结点)根据定义G仍是树,(根据n=k时的假设2)G有k个节点,故有k-1条边,从而m=(k-1)+1=k=n-1(将u结点加回来,边数相应地增加1)。(即若n=k时命题成立则n=k+1时命题也成立,那么从n=1开始构建任意结点数量的树也满足m=n-1)

该证明过程充分体现了树在逻辑上是递推构建起来的图:

分析树的构建图解可知:

  • 若构建仅有一个根结点的有向树,则该有向树的每棵子树的根结点有且只有一个父节点可以有0个或多个孩子结点.
  • 同时易知:在仅有一个根结点的树形结构中,一棵树的子树之间不存在通路

3.有序有向树

满树的概念:

  • 设(单个根结点)树T的高度为h(h>1),度为k(k>=1)(树的结点个数大于1)
  • 树T对应的满树的概念:高度为h根结点每一个分枝结点的出度都为k的树
  • 有序有向树的每一个结点都有自己固定的编号

 有序有向树各结点的编号规则:

  1. 设现在有一颗高度为h,度为k的(单个根结点的)树T(h>1,,k>=1)
  2. 先作出树T对应的满树
  3. 树T对应的满树的各结点按照从低层到高层,从左往右的次序进行编号
  4. 根据满树各结点的编号对树T相应位置的结点进行编号

比如:

二.数据结构中树的顺序存储结构与链式存储结构

如果将树的结点看成是一个个内存区块,结点间的有向线段看成是各内存区块之间的关联(这种关联可能是通过指针或者数组下标关系建立起来的),这种在内存中形成的数据结构就是树形数据结构

1.数据结构的物理结构与逻辑结构

  • 数据结构的物理结构指的是该数据结构在内存中的真实分布模型
  • 数据结构的逻辑结构指的是数据结构的抽象分析模型

数据结构的类型主要取决于其逻辑结构,其逻辑结构和物理结构之间是通过逻辑映射来建立联系的

2.物理结构为顺序表(数组)的树形数据结构

  • 现有一颗度数为2的非满树T
  • 我们先将一个树T对应的满树的各个结点按照从低层次到高层次,从左往右的顺序进行编号:
  •  由此我们可以得到树T各个结点的编号:
  • 根据树T各结点的编号我们就可以将这棵树映射到一个数组上去:
  • 通过结点编号与数组下标的绝对映射,我们便可以通过数组来实现树形数据结构(有序有向树) 
  • 顺序表实现的树中,非常经典的例子就是堆(大小根堆)

3. 物理结构为链表的树形数据结构

我们可以定义一个结构体类型:

typedef int DataType;
struct Node
{struct Node* _firstChild1;  // 第一个孩子结点struct Node* _pNextBrother; // 指向其下一个兄弟结点DataType _data;             // 结点中的数据域
};
  • _firstChild1用于指向该结点的第一个孩子结点(编号意义上的第一个(位于左侧))
  • _pNextBrother用于指向与该结点位于相同层次具有相同父结点兄弟结点

现在有一颗树:

我们用链式存储结构来实现它:

通过_firstChild1指针我们可以实现树的深度遍历

通过_pNextBrother指针我们可以实现树的广度遍历

三.二叉树

1.二叉树基本概念 

一棵二叉树是结点的一个有限集合:

  1. 二叉树的度为2,即不存在出度大于2的结点
  2. 二叉树结点的孩子结点有左右之分(左右孩子),次序不能颠倒,二叉树是有序有向树(各结点都有自己对应的固定编号)

对于任意的二叉树都是由以下几种情况复合而成

2.两个重要的特殊二叉树

  • 满二叉树:一个二叉树,如果根结点和每一个分枝结点的出度都为2,则这个二叉树就是满二叉树。从结点总个数角度分析:如果一个二叉树的层数为K,且结点总数是2^k - 1(等比数列求和),则它就是满二叉树.
  • 完全二叉树:完全二叉树是效率很高的数据结构;
    对于高度为K的,有n个结点的二叉树,当且仅当其所有结点编号为1到n连续排列时称之为完全二叉树。(基于完全二叉树的结点编号特点,用数组来实现完全二叉树,内存利用率较高)

完全二叉树有一个特点:

若完全二叉树的高度为k(k>1),则其前k-1层所有结点构成的子结构是一颗满树

  •  用数组实现完全二叉树非完全二叉树的对比:可见完全二叉树的优势所在
  •  数据结构堆就是用顺序表(数组)实现的完全二叉树(堆是堆排序算法的结构基础)

3. 关于二叉树的一些常用数学结论

接下来我们给出两组在后续的算法学习中会用到的关于二叉树的数学结论

(1).第一组结论 

  • 对任何一棵二叉树, 如果出度为0其叶结点个数为N0, 出度为2的分支结点个数为N2(包括根) ,则有 N0= N2+1

证明:

设该二叉树出度为1的分枝结点个数为N1;

该二叉树中的总边数为: 2*N2 + N1;

二叉树中的总结点个数为: N0 + N1 + N2

根据第一章第2小节的基本数学结论有:2*N2 + N1 = N0 + N1 + N2 -1(树的总边数 = 结点数-1)

化简可得:N0 = N2 +1;(即二叉树中,出度为0的树叶永远比出度为2的分枝结点(包括根)多一个)

(2).第二组结论(数组实现二叉树的算法基础)

  • 定理一:对于具有n个结点的完全二叉树,按照第一章第3节所述的编号规则将其各结点进行编号(根结点我们规定编为0号,则完全二叉树的各结点编号为0~n-1),则对于编号为child的结点有如下结论:若child>0,child编号结点的父结点编号parent = (child-1)/2;若child=0 ,该结点无父结点 

定理一证明图解:

  • 定理二:对于具有n个结点的完全二叉树,按照第一章第3节所述的编号规则将其各结点进行编号(根结点我们规定编为0号,则完全二叉树的各结点编号为0~n-1),则对于编号为parent的结点有如下结论:2*parent+1<n,则可得该结点的左孩子结点编号leftchild = 2*parent+1;若2*parent+1>=n,则该结点无左孩子(该结论是定理一的逆定理)
  • 定理三:对于具有n个结点的完全二叉树,按照第一章第3节所述的编号规则将其各结点进行编号(根结点我们规定编为0号,则完全二叉树的各结点编号为0~n-1),则对于编号为parent的结点有如下结论:若2*parent+2<n,则可得该结点的右孩子结点编号rightchild = 2*parent+2;若2*parent+2>=n该结点无右孩子(该结论是定理一的逆定理)

定理二和三的证明分析图解:

有了该组定理我们就可以通过一个父结点的编号找到其左右孩子结点的编号,反过来也可以通过孩子结点的编号找到其父结点的编号(该组定理为数组实现二叉树奠定了算法基础)

  • 该组定理在后续堆的实现中的堆元素插入删除接口元素上下调整算法中会用到

相关文章:

数据结构:二叉树概念篇(算法基础)

目录 一.有向树的图论基础 1.有向树的相关基本概念 有向树的基本定义: 有向树的结点的度&#xff1a; 有向树的度: 有向树的根结点,分枝结点,叶结点: 树的子树: 树结点的层次: 树的高度: 2.一个基本的数学结论 3.有序有向树 二.数据结构中树的顺序存储结构与链式存…...

华为OD机试真题Java实现【字符串变换最小字符串】真题+解题思路+代码(20222

字符串变换最小字符串 给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。 变换规则:交换字符串中任意两个不同位置的字符。 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Java)真题目录汇总 ## 输入输出描述: …...

数字化转型的企业会用低代码平台深化重塑什么形态

随着数字化转型的浪潮不断推进&#xff0c;越来越多的企业开始关注如何更好地利用数字技术提高业务效率和创新能力。而低代码平台作为一种能够快速构建和部署应用程序的新型工具&#xff0c;正越来越受到企业的青睐。那么&#xff0c;数字化转型的企业会用低代码平台深化重塑什…...

【华为OD机试模拟题】用 C++ 实现 - 拼接 URL(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...

六千字让你明白什么是数字孪生?

文章目录1. 背景2. 数字孪生基础2.1 概念2.2 价值3. 技术生态3.1 技术体系3.2 核心技术3.2.1 多领域、多尺度融合建模3.2.2 数据驱动与物理模型融合的状态评估3.2.3 数据采集和传输3.2.4 全生命周期数据管理3.2.5 虚拟现实呈现3.2.6 高性能计算3.3 建设3.3.1 重点3.3.1.1 数字孪…...

判断字符串是否是纯数字不包括符号(含符号显示False)isnumeric()和isdigit()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断字符串是否是纯数字 不包括符号&#xff08;含符号显示False&#xff09; isnumeric()和isdigit() [太阳]选择题 对于代码中当s为‘二十六’时isdigit()和isnumeric()输出的结果是? s …...

计算机408考研先导课---C语言难点2

目录 一、字符型数据与字符串型数据的比较 1、字符型数据特点 2、字符串型数据特点 二、字符数组 1、定义 2、输入输出 ①输入 ②输出 3、字符处理函数 ①put函数 ②gets函数 ③strcat函数 ④strcpy函数 ⑤strcmp函数 ⑥strlen函数 ⑦strlwr函数 ⑧strup…...

682. 棒球比赛

题目&#xff1a;你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成&#xff0c;过去几回合的得分可能会影响以后几回合的得分。 比赛开始时&#xff0c;记录是空白的。你会得到一个记录操作的字符串列表 ops&#xff0c;其中 ops[i] 是你需要记录的第 i 项操…...

【《C Primer Plus》读书笔记】第13章:文件输入/输出

【《C Primer Plus》读书笔记】第13章&#xff1a;文件输入/输出13.1 与文件进行通信13.1.1 文件是什么13.1.2 文本模式和二进制模式13.1.3 I/O的级别13.1.4 标准文件13.2 标准I/O13.3 一个简单的文件压缩程序13.4 文件I/O&#xff1a;fprintf()、fscanf()、fgets()和fputs()13…...

Datacom-HCIE考试经验分享

我是誉天Datacom秦同学。作为誉天众多通过Datacom-HCIE考试的学员之一&#xff0c;我感到很荣幸。 首先说说自学的感受吧&#xff1a; 我是从2020年开始接触网络行业的&#xff0c;听单位的前辈说华为的HCIE认证是行业含金量最高的证书&#xff0c;从那时起心里就种下了一个“I…...

第十二章 系统错误消息 - 一般系统错误消息 P - S

文章目录第十二章 系统错误消息 - 一般系统错误消息 P - S第十二章 系统错误消息 - 一般系统错误消息 P - S 错误代码描述<PARAMETER>由用户编写的函数引用或 Do 命令传递给标记行的参数数量超过了为标记行声明的形式参数的数量。<PRIVATE METHOD>已尝试调用一个私…...

【git】Idea中git的使用

配置git 创建git仓库 不同颜色代表的含义 红色——未加入版本控制&#xff1b;绿色——已经加入控制暂未提交&#xff1b;蓝色——加入&#xff0c;已提交&#xff0c;有改动&#xff1b;白色——加入&#xff0c;已提交&#xff0c;无改动&#xff1b;灰色——版本控制已忽略文…...

Centos安装Python、PyCharm

安装Python 1、打开终端(Terminal) 2、输入以下命令更新系统&#xff1a; sudo yum update 3、安装Python&#xff1a; sudo yum install python3 4、安装完成后&#xff0c;可以使用以下命令检查Python版本&#xff1a; python3 --version 安装PyCharm 1、下载PyCharm的安…...

搞百亿补贴,京东不能只“砸钱”

出品 | 何玺 排版 | 叶媛 京东“百亿补贴”真的要来了。 据多家媒体报道&#xff0c;京东“百亿补贴”已于2月23日启动内测。根据此前消息&#xff0c;京东“百亿补贴”频道将于3日晚8点正式上线。 在京东“百亿补贴”频道正式上线之前&#xff0c;我们来聊一聊“刘强东为什…...

automl介绍以及代码实例

使用AutoML来自动构建机器学习模型&#xff0c;可以使用多种不同的Python包&#xff0c;包括AutoGluon、TPOT、Auto-Keras等。AutoGluon可以自动搜索最佳模型&#xff0c;以便满足开发人员的需求&#xff1b;TPOT可以自动调整模型的参数&#xff0c;以获得更好的性能&#xff1…...

kill 与killall

【查询命令所属软件包】 rpm -qf /usr/bin/killall psmisc-22.20-15.el7.x86_64 rpm -qf /usr/bin/kill util-linux-2.23.2-65.el7_9.1.x86_64 【命令参数】 killallkill -e,--exact require exact match for very long names -I,--ignore-case case insensi…...

【加密】开发常见加密类型

相关加密方法具体使用&#xff0c;查阅工具官方&#xff1b; 对称加密&#xff08;单密钥加密&#xff09;&#xff1a;常用于传输数据加密 信息的加密和解密使用相同密钥&#xff1b; 常见对称算法&#xff1a; DES&#xff08;Data Encryption Standard&#xff09;&#x…...

数据结构之基:从根儿上了解数据结构的特性

学好数据结构&#xff0c;就等于成功了一半。 程序是对现实的模拟&#xff0c;现实是由时间和空间组成的&#xff0c;高效的人都是用最少的时间、最少的空间来做最伟大的事&#xff0c;程序亦是如此。我们要选择最合理的算法和最合理的数据结构&#xff0c;来写最好的代码&…...

C++ 枚举详解

C 枚举详解 C 枚举类型详解 枚举类型的定义格式为&#xff1a; enum <类型名> {<枚举常量表>};关键字enum——指明其后的标识符是一个枚举类型的名字枚举常量表——由枚举常量构成。“枚举常量"或称"枚举成员”&#xff0c;是以标识符形式表示的整型量&…...

【vue3】ref , reactive ,toRef ,toRefs 使用和理解

这篇文章是基于理解写的&#xff0c;仅助于理解&#xff0c;如有任何错误之处&#xff0c;感谢指正&#xff01; 文章目录一.ref的使用1. ref的功能主要有两个&#xff1a;2.使用ref注意事项二.reactive的使用三.使用ref 和 reactive 实现双向数据绑定四.toRef 和 toRefs 的使用…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...