C++高级数据结构算法 | 树与二叉树的基本概念与性质

版权声明:本文为博主整理文章,未经博主允许不得转载。 https://blog.csdn.net/ZYZMZM_/article/details/90633665

之前我们有讲解过基础的数据结构算法:线性表、栈和队列、串的相关概念,以及八大排序算法及其代码实现。

从本篇博文开始,我们将讲解高级数据结构算法,使用C++语言实现,包括BST树、AVL树、红黑树、跳跃表、字典树、倒排索引以及分治法、贪心算法、回溯算法、动态规划、分支限界算法等高级数据结构算法。



树的基本概念

之前我们讲解的都是一对一的线性结构,可现实中,还有很多一对多的情况需要处理,所以我们需要研究这种一对多的数据结构——“树”,考虑它的各种特性,来解决我们在编程中遇到的相关问题。

下面是引用百科词条的解释:

树状图是一种数据结构,它是由 n ( n 0 ) n ( n ≥ 0 ) 个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

  • 每个结点有零个或多个子结点
  • 没有父结点的结点称为根结点
  • 每一个非根结点有且只有一个父结点
  • 除了根结点外,每个子结点可以分为多个不相交的子树

树的定义:

树(Tree)是 n ( n 0 ) n (n≥ 0) 个结点的有限集 n = 0 n = 0 时称为空树。在任意一颗非空树中:

  • 有且只有一个特定的称为根(root)的结点
  • n > 1 n > 1 时,其余结点可分为 m ( m > 0 ) m (m > 0) 个互不相交的有限集 T 1 T 2 T m T_1、T_2、···、T_m ,其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。如下图所示:

树的定义其实就是一种典型的递归的方法,也就是说在树的定义的中也用到了树的概念。下图中子树 T 1 T_1 和子树 T 2 T_2 就是根结点A的子树,D、G、H、I组成的树又是以B为根节点的子树,E、J组成的树是以C为根节点的子树。

对于树的定义还要强调两点:

  • n > 0 n > 0 时根节点是唯一的,既不可能存在多个根节点
  • m > 0 m > 0 时,子树的个数没有限制,但它们一定是互不相交的

结点分类

树的结点包含一个数据元素及若干指向其子树的分支。结点拥有的子树数称为结点的度(Degree)度为0的结点称为叶子节点(Leaf)或终端结点;度不为0的结点称为非终端结点或分支结点。除根节点外,分支结点也称为内部结点。树的度是树内各结点度的最大值

如下图,这棵树结点的度的最大值是结点D的度,度为3,因此树的度也是3。


结点间关系

结点的子树的根称为该结点的孩子(child),通常我们称其为子结点,相应的,该结点称为孩子的双亲(parent),通常我们称为父节点

同一个双亲的孩子之间互称为兄弟(Sibling)。结点的祖先是从根到该结点所经分支上的所有结点。 反之,以某结点为根的子树中的任一结点都统称为该结点的子孙。

在下图中,对于H来说,D、B、A都是它的祖先。B的子孙有D、G、H、I。


树的其他相关概念

结点的层次(Level)是从根开始定义的,根为第一层,根的孩子为第二层。若某结点在第 i i 层,那么其子树的根就在第 i + 1 i+1 层。其双亲在同一层的结点互为堂兄弟树中结点的最大层次称为树的深度(Depth)或高度

在下图中,G、H、I 与 J 是堂兄弟,当前树的深度为4。

如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树是有序树,否则称为无序树

森林(Forest)是 m m 0 m(m ≥ 0) 棵互不相交的树的集合对树中每个结点而言,其子树的集合即为森林


有关树的基本概念整理

  • 节点的度:一个节点含有的子树的个数称为该节点的度。
  • 叶节点或终端节点:度为0的节点称为叶节点;
  • 非终端节点或分支节点:度不为0的节点;
  • 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
  • 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
  • 兄弟节点:具有相同父节点的节点互称为兄弟节点;
  • 树的度:一棵树中,最大的节点的度称为树的度;
  • 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
  • 树的高度或深度:树中节点的最大层次;
  • 堂兄弟节点:双亲在同一层的节点互为堂兄弟;
  • 节点的祖先:从根到该节点所经分支上的所有节点;
  • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
  • 森林:由 m m 0 m(m≥0) 棵互不相交的树的集合称为森林。

树的存储结构

树中的某个结点的孩子可以有多个,所以仅仅使用简单的顺序结构或者链式结构是不能完全表示一整棵树的。

充分利用顺序存储结构和链式存储结构的特点,完全可以实现对树的存储结构的表示

我们表示一棵树的方法有:双亲表示法,孩子表示法,孩子兄弟表示法

有关树的存储结构的详细讲解,可以参考博文:《树的存储结构》


二叉树的定义

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

下图便是一棵二叉树:

二叉树的特点

二叉树的特点有:

  • 每个结点最多有两棵子树,所以二叉树中不存在度大于 2 的结点。注意不是只有两棵子树,而是最多有。没有子树或者有一棵子树都是可以的。
  • 左子树和右子树是有顺序的,次序不能任意颠倒。
  • 即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。

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

  • 空二叉树
  • 只有一个根结点
  • 根结点只有左子树
  • 根结点只有右子树
  • 根结点既有左子树又有右子树

特殊的二叉树

1、斜树

所有的节点都只有左子树的二叉树叫左斜树所有节点都只有右子树的二叉树叫右斜树。这两者统称为斜树。

斜树的特点很明显就是每一层只有一个节点,节点的个数与二叉树的深度相同。其实线性表可以理解为树的一种极其特殊的形式。


2、满二叉树

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

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

  • 叶子只能出现在最下一层。 出现在其它层就不可能达成平衡。
  • 非叶子节点的度一定是2。
  • 在同样深度的二叉树中,满二叉树的节点个数最多,叶子数最多。

3、完全二叉树

对于一棵具有 n n 个节点的二叉树按照层序编号,如果编号为 i i 1 i n 1≤ i ≤ n )的节点与同样深度的满二叉树中编号为 i i 的节点在二叉树中位置完全相同,则这棵二叉树称为”完全二叉树“。如下图:
在这里插入图片描述
把完全二叉树的节点与同样深度的满二叉树各个节点进行编号比较,所有节点出现的位置相同,则是完全二叉树。所以,满二叉树一定是一棵完全二叉树,而完全二叉树不一定是满二叉树。

完全二叉树的特点:

  • 叶子节点只能出现在最下两层。
  • 最下层的叶子一定集中左部连续位置。
  • 倒数第二层,若有叶子节点,一定都在右部连续位置。
  • 如果节点度为1,则该节点只有左孩子,即不存在右子树的情况。
  • 同样节点的二叉树,完全二叉树的深度最小。

二叉树的性质

性质1:在二叉树的第 i i 层上至多有 2 i 1 2^{i-1} 个结点(i ≥ 1)

性质2:深度为 k k 的二叉树至多有 2 k 1 2^k-1 个结点(k ≥ 1)

性质3:对任何一棵二叉树 T,如果其终端结点数为 n 0 n_0 ,度为2的节点数为 n 2 n_2 ,则 n 0 = n 2 + 1 n_0=n_2+1

性质4:具有 n n 个结点的完全二叉树的深度为 l o g 2 n + 1 \lfloor log_2n \rfloor+1 (其中 x \lfloor x\rfloor 表示向下取整,即表示不大于 x x 的最大整数)

性质5:如果对一棵有 n n 个结点的完全二叉树(其深度为 l o g 2 n + 1 \lfloor log_2n \rfloor+1 )的结点按层序编号(从第 1 1 层到第 l o g 2 n + 1 \lfloor log_2n \rfloor+1 层,每层从左到右),对任一结点 i 1 i n i(1≤i≤n) 有:

  • 如果 i = 1 i=1 ,则结点 i i 是二叉树的根,无双亲;如果 i > 1 i>1 ,则其双亲是结点 i / 2 \lfloor i/2 \rfloor
  • 如果 2 i > n 2i>n ,则结点 i i 无左孩子(结点 i i 为叶子结点);否则其左孩子是结点 2 i 2i
  • 如果 2 i + 1 > n 2i+1>n ,则结点 i i 无右孩子;否则其右孩子是结点 2 i + 1 2i+1

猜你喜欢

转载自blog.csdn.net/ZYZMZM_/article/details/90633665