数据结构 | 二叉树

1. 二叉树的定义

现在我们来做个游戏,我在纸上已经写好了一个 100 以内的正整数数字,请大家想办法猜出我写的是哪一个?猜的次数不能超过 7 个,我的回答只会告诉你是"大了" 或 "小了"。

这个游戏在一些电视节目中,猜测一些商品的定价时常会使用。我看到过有些人是一点一点的数字累加的,比如5、10、15、20 这样猜,这样猜数策略太低级了,显然是没有学过数据结构和算法的人才做得出的事。

其实这是一个很经典的折半查找算法。用下图的办法,就一定能在 7 次以内猜出结果来。(下三层省略)

由于是 100 以内的正整数,所以我们先猜 50(100的一半),被告之 "大了",于是再猜 25(50的一半),被告之 "小了",再猜 37(25与50的中间数),小了,于是猜 43,大了,40,大了,38,小了,39,完全正确。

被猜数字第一次第二次第三次第四次第五次第六次第七次
3950253743403839
8250758882
99507588969899
15025126321

我们发现,如果用这种方式进行查找,效率高的不是一点点。对于这种在某个阶段都是两种结果的情形,比如开和关、0 和 1、真 和 假、上和下、对与错,正面与反面等,都适用树状结构来建模,而这种树是一种很特殊的树状结构,叫作二叉树。

二叉树(Binary Tree) 是 n (n≥0) 个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。

1.1 二叉树特点

二叉树的特点有:

  • 每个结点最多有两棵子树,所以二叉树中不存在度大于 2 的结点。注意不是只有两棵子树,而是最多有,没有子树或者有一棵子树都是可以的。
  • 左子树和右子树是有顺序的,次序不能任意颠倒。就像人是双手、双脚,但显然左手、左脚和右手、右脚是不一样的,右手戴左手表、右脚穿左鞋都会极其别扭和难受。
  • 即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。

二叉树具有五种基本形态:

  1. 空二叉树。
  2. 只有一个根结点。
  3. 根结点只有左子树。
  4. 根结点只有右子树。
  5. 根结点既有左子树又有右子树。

1.2 特殊二叉树

斜树

顾名思义,斜树一定要是斜的,但是往哪斜还是有讲究。 所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树。 斜树有很明显的特点,就是每一层都只有一个结点,结点的个数与二叉树的深度相同。

有人会想,这也能叫树呀,与我们的线性表结构不是一样吗。对的,其实线性表结构就可以理解为是树的一种极其特殊的表现形式。

满二叉树

"水满则溢,月盈则亏"。不完满才是人生,我们通常举的例子也都是左高右地、参差不齐的二叉树。那是否存在完美的二叉树呢?

在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。

但是每个结点都存在左右子树,不能算是满二叉树,还必须要所有的叶子都在同一层上,这就做到了整棵树的平衡。因此,满二叉树的特点有:

  1. 叶子只能出现在最下一层。出现在其他层就不能达成平衡。
  2. 非叶子结点的度一定是2。否则在其他层就不可能达成平衡。
  3. 在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。

完全二叉树

对一棵具有 n 个结点的二叉树按层序编号,如果编号为 i(1<i<n)的结点与同样深度的满二叉树中编号为 i 的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。

满二叉树一定是一棵完全二叉树,但完全二叉树不一定是满的。

完全二叉树的特点:

(1)叶子节点只能出现在最下两层。

(2)最下层的叶子一定集中在左部连续位置。

(3)倒数二层,若有叶子结点,一定都在右部连续位置。

(4)如果结点度为 1,则该结点只有左子树,不存在只有右子树的情况。

(5)同样节点数的二叉树,完全二叉树的深度最小。

判断某二叉树是否是完全二叉树的办法,就是看着树的示意图,心中默默给每个结点按照满二叉树的结构逐层顺序编号,如果编号出现空挡,就说明不是完全二叉树。否则就是。

2. 二叉树的性质

2.1 二叉树性质 1

2.2 二叉树的性质 2

2.3 二叉树的性质 3

2.4 二叉树的性质 4

2.5 二叉树的性质 5

3. 遍历二叉树

3.1 二叉树的遍历原理

二叉树的遍历(traversing binary tree)是指从根节点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。

这里有两个关键词:访问和次序。

访问其实是要根据实际的需要来确定具体做什么,比如对每个结点进行相关计算,输出打印等,它算作是一个抽象操作。在这里我们可以简单地假定就是输出结点的数据信息。

二叉树的遍历次序不同于线性结构,最多也就是从头至尾、循环、双向等简单的遍历方式。树的结点之间不存在唯一的前驱和后继关系,在访问一个结点后,下一个被访问的结点面临着不同的选择。

3.2 二叉树的遍历方式

二叉树的遍历方式可以很多,如果我们限制了从左到右的习惯方式,那么主要就分为四种:

1、前序遍历

规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再谦虚遍历右子树。如图,遍历的顺序为:ABDGHCEIF

 

2、中序遍历

规则是若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。如图,遍历的顺序为:GDHBAEICF。

 

3、后序遍历

规则是若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。 遍历的顺序为:GHDBIEFCA。

 

4、层序遍历

规则若是树为空,则空操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。如图:遍历的顺序为:ABCDEFGHI。

 

有同学会说,研究这么多遍历的方法干什么呢?

我们用图形的方式来表现树的结构,应该说是非常直观和容易理解,但是对于计算机来说,它只有循环、判断等方式来处理,也就是说,它智慧处理线性序列,而我们刚才提到的四种遍历方法,其实都是在把树中的结点变成某种意义的线性序列,这就给程序的实现带来了好处。

另外不同的遍历提供了对结点依次处理的不同方式,可以在遍历过程中对结点进行各种处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值