作为数据结构的基础,树分很多种,像AVL树、红黑树、二叉搜索树....今天我想分享的是关于二叉树,一种基础的数据结构类型。
01
什么是树
在《数据结构》[注1]中树有如下定义:
树是 n(n≥0) 个结点的有限集
在此我对上述定义做出如下解释:
当n=0n=0时,为空树,树的深度与高度均为00,是树的一种特例;当n>0n>0时,为非空树,树的第一个结点,即深度为11的结点,我们称其为根结点,由根结点可以引出若干子树分支,同时子树分支可依此向下延伸,此时树的深度与高度也在变化,即树状图。
这里我们需要厘清树的深度与树的高度与其他树的术语:
树的深度:树中结点的最大层次
树的高度:从叶子结点开始定义,叶子结点为第一层,往上依次递增,直至根结点。
结点:树的结点包含一个数据元素以及若干指向其子树的分支
度:结点所拥有的子树数量
终端节点:度为0的结点称为叶子结点或终端结点
树的度:树中各结点度的最大值
层次:从根开始定义,根为第一层,依次递增
有序树:树中结点的各子树从左往右是有次序的,不可相互交换;反之则是无序树
森林:一棵非空树删掉根结点,即是森林
02
二叉树的概念引入
二叉树是由树演化而来的一种数据结构,上面所有术语均适用于二叉树。二叉树与树不同之处在于,树的每一个结点(除终端结点外)允许有若干子树分支;而二叉树只允许有左右两个子树分支,即不存在度大于2结点。
C语言示例:

上面的示例清晰地阐明了二叉树的结点是由一个数据元素和两个子树分支构成,需要明确的是,虽然终端结点没有指向任何子树,但它仍旧有往下繁衍的能力。
除此之外,二叉树还是一棵有序树,它的各个结点从左到右是依次有序可循的,且不可交换;它具有以下五种形态:
空树
仅有根结点
左子树为空
右子树为空
左右子树均非空
当二叉树处于第五种状态,且设树的深度为n,总结点数为
时,我们称其为满二叉树。
事实上还有另外一种也处于第五状态的树——完全二叉树。由于完全二叉树的定义在每个版本的教科书中均不相同,而笔者只接触过《数据结构·严蔚敏版》,因此摘录此书中对完全二叉树的定义:

深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为完全二叉树。
这段描述我读了两遍,方才理解其中的深刻含义,我们把深度为3的满二叉树的每个结点从上往下,从左往右进行编号:

然后我们再定义一棵深度也为3的二叉树,该二叉树的n 个结点(n≤7),当从1到n的每个结点都与上图中的编号结点一一对应时,这二叉树就称为完全二叉树。
举个例子,当n=5时:

这便是完全二叉树。
因此我们还可以得到一个推论:满二叉树是完全二叉树,但完全二叉树不一定是满二叉树。
当二叉树处于第三种状态时,称其为右斜树。

同理,处于第四状态为左斜树。

03
二叉树的性质总结
二叉树的第i 层上最多有
个结点。此性质可通过上面满二叉树的图示推得
深度为n 的二叉树,最多拥有
个结点。此性质可以通过数列求和得出:

设满二叉树深度为 n,叶子结点数必为
设任意一棵二叉树的叶子结点数为n0,度为1的结点数为n1,度为2的结点数为n2;总结点数为n。则有:

设分支的总边数为x,则有:

联立上述三式可得:

即任意二叉树的叶子结点数为该树中度为2的结点数的总和加一。
设一完全二叉树具有n个结点,则其深度必为
,[x]表示不大于x的最大整数,即向下取整。
04
手把手建立二叉树
C语言示例:


其中需要指明的是二叉树的三种遍历方法:先序遍历、中序遍历、后序遍历。
先序遍历
即遍历顺序为“根—>左->右”。
中序遍历
即遍历顺序为“左—>根—>右”,由于二叉树为有序树,因此中序遍历输出的值由小到大的。
后序遍历
即遍历顺序为“左—>右—>根”。
还有一种遍历法,称为层序遍历,有兴趣的读者可以尝试着写一下。
相关推荐
u-boot有一个功能强大的驱动模型,这一点与linux内核一致。驱动模型对设备驱动相关操作做了一个....
学术界已有不少研究工作来加速 NeRF。比较流行的一种方式是, 给定训练好的 NeRF, 采用更高效....
我们以中序遍历为例,在二叉树:听说递归能做的,栈也能做!中提到说使用栈的话,无法同时解决访问节点(遍....
发表于 08-03 11:22 •
51次
阅读
本文以四个方面介绍epoll的实现原理,1.epoll的数据结构;2.协议栈如何与epoll通信;3....
精简之后的代码根本看不出是哪种遍历方式,也看不出递归三部曲的步骤,所以如果对二叉树的操作还不熟练,尽....
递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时....
发表于 07-25 15:40 •
56次
阅读
在内核初始化的过程中需要分配内存,内核提供了临时的引导内存分配器,在页分配器和块分配器初始化完毕后,....
我们在栈与队列:匹配问题都是栈的强项中提到了,递归的实现就是:每一次递归调用都会把函数的局部变量、参....
一直跟着公众号学算法的录友 应该知道,我在二叉树:构造二叉树登场!,已经讲过,只有 中序与后序 和 ....
相信很多同学对递归算法的时间复杂度都很模糊,那么这篇Carl来给大家通透的讲一讲。
身为深开鸿 OS 内核开发师,我们常年深耕于 OpenHarmony 的内核开发,希望通过分享一些工....
深开鸿 发表于 07-12 16:45
•
363次
阅读
通常我们可以通过UART,I2C,SPI等接口将数据读取到单片机内部。很多情况下,数据的更新频率很高....
发表于 07-08 16:33 •
111次
阅读
以前用单片机做用户交互的菜单的时候,都比较痛苦,如何写一个复用性高,方便维护,可扩展性高的GUI框架....
硬件攻城狮 发表于 07-08 14:27
•
295次
阅读
现在给你一个不包含重复单词的单词列表wordDict和一个字符串s,请你判断是否可以从wordDic....
在产品研制和生产过程中,不同的部门结合各自任务将各个阶段的产品信息划分为不同的BOM信息。BOM的数....
今天推荐一个适用于单片机裸机开发的开源轮子。
发表于 07-04 18:38 •
1031次
阅读
./oschina_soft/assimp.zip
发表于 06-16 09:53 •
45次
阅读
近年来,国内开源实现跨越式发展,并成为企业提升创新能力、生产力、协作和透明度的关键。作为 OpenA....
由于需要在内核中进行代码测试验证,完整编译安装内核比较耗时耗力。准备采用module形式来验证。
发表于 05-18 20:13 •
568次
阅读
主要内容:从应用程序发起一次IO行为,最终怎么到磁盘,以及在这个路径上有什么trace的方法和 配置....
发表于 05-16 09:23 •
412次
阅读
这里主要总结下在工作中常碰到的几种数据结构:Array,ArrayList,List,LinkedL....
该文档在概要设计的基础上,进一步的细化系统结构,展示了软件结构的图标,物理设计、数据结构设计、及算法....
硬件攻城狮 发表于 05-13 14:23
•
514次
阅读
在linux内核中,互斥量(mutex,即mutual exclusion)是一种保证串行化的睡眠锁....
书生途 发表于 05-13 08:56
•
4529次
阅读
Trie 树又叫字典树、前缀树、单词查找树,是一种二叉树衍生出来的高级数据结构,主要应用场景是处理字....
如果你对Linux是如何实现 对用户原始的网络包进行协议头封装与解析,为什么会粘包拆包,期间网络包经....
遍历顺序上依然是后序遍历(因为要比较递归返回之后的结果),但在处理中间节点的逻辑上,最大深度很容易理....
expan.zip
发表于 04-27 11:22 •
70次
阅读
用抽象的语言描述解决特定问题的每一步的操作。程序是计算机能理解和执行的指令序列。一个程序实现一个算法....
数据的运算其实就是大家熟悉的增删改查,不过相比数据库现成的SQL,数据结构实现起来有很多细节需要考虑....
gitee-WeCross.zip
发表于 04-22 10:51 •
51次
阅读
完全二叉树:完全二叉树是效率很高的数据结构。对于深度为K,有n个节点的二叉树,当且仅当每一个节点都与....
redisbook.zip
发表于 04-20 11:20 •
52次
阅读
cgroup最基本的操作时我们可以使用以下命令创建一个cgroup文件夹
OpenDSA.zip
发表于 04-19 10:10 •
75次
阅读
选择一种合适的数据结构很重要,如果在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多....
编程的基础-算法和数据结构入门资料免费下载。
发表于 04-18 09:35 •
62次
阅读
关于数据结构与方法的经典教材免费下载。
发表于 04-02 16:56 •
98次
阅读
计算机408考研指定专业用书之一数据结构(C语言版)教材下载。
发表于 03-31 15:25 •
213次
阅读
1.前情概览
我们在前片博客中讲述了 proxy - stub 架构的一般编程范式,这篇文章关注驱动自身的数据传输,做一次完整的数据分析...
发表于 03-30 09:26 •
1741次
阅读
二叉查找树也叫二叉搜索树,也叫二叉排序树,它具有以下特点:1. 如果左子树不为空,则左子树上的结点的....
为了让大家掌握多种排序方法的基本思想,本篇文章带着大家对数据结构的常用七大算法进行分析:包括直接插入....
C++相关题目下载。
发表于 02-21 15:58 •
67次
阅读
串口队列环形缓冲区队列串口环形缓冲的好处代码实现队列 要实现队列环形缓冲,还需要一定的数据结构知识。队列是一种重要的数...
发表于 02-21 07:11 •
480次
阅读
单片机电路元件以及读数方法讲解((贴片)电阻,电容,二极管,蜂鸣器等)***1. 电阻和贴片电阻读数2. 电容3. 二极管读数计算及...
发表于 02-18 07:16 •
449次
阅读
1:如果串口带有奇偶校验,则需要设置32的串口字长为9位数据格式才行,否则会乱码2:如果在ucos中使用浮点数,尽量使用__align(8) 对齐...
发表于 02-18 07:15 •
691次
阅读
工业控制生产要求一体化操作更加紧密,人机交互更加频繁,所以工业一体机几乎全部采用触摸屏方式替代鼠标键盘(紧急场合保留几个...
发表于 02-16 06:37 •
516次
阅读
提供完整的解决思路和可运行的代码
发表于 02-14 07:25 •
185次
阅读
表
发表于 02-14 07:22 •
425次
阅读
W25Q128 将 16M 的容量分为 256 个块(Block),每个块大小为 64K 字节,每个块又分为 16个扇区(Sector),每个扇区 4K ...
发表于 02-14 07:19 •
211次
阅读
线
发表于 02-14 06:13 •
322次
阅读
环
发表于 02-14 06:02 •
736次
阅读
Linux内核主要学习内容可以分为三大块:进程、内存及协议栈。今天就说说内存泄露的问题。相信你在平时....
发表于 01-14 13:02 •
91次
阅读
串口队列环形缓冲区队列串口环形缓冲的好处代码实现队列 要实现队列环形缓冲,还需要一定的数据结构知识....
发表于 12-24 19:04 •
200次
阅读
1:如果串口带有奇偶校验,则需要设置32的串口字长为9位数据格式才行,否则会乱码2:如果在ucos中....
发表于 12-23 19:58 •
86次
阅读
单片机电路元件以及读数方法讲解((贴片)电阻,电容,二极管,蜂鸣器等)***1. 电阻和贴片电阻读数....
发表于 12-23 18:59 •
220次
阅读
工业控制生产要求一体化操作更加紧密,人机交互更加频繁,所以工业一体机几乎全部采用触摸屏方式替代鼠标键....
发表于 12-20 18:56 •
108次
阅读
W25Q128 将 16M 的容量分为 256 个块(Block),每个块大小为 64K 字节,每个....
发表于 12-09 15:36 •
154次
阅读
提供完整的解决思路和可运行的代码
发表于 12-09 13:51 •
128次
阅读
评论