数据结构与算法——树与二叉树


回顾

  • 递归方法常用于以下三种情况:

    • 定义是递归的
    • 数据结构是递归的
    • 问题的解法是递归的
  • 递归思路:将一个大问题分解成小问题来解决,然后进一步将这些小问题分解成更小的问题,直到每个小问题都可以直接解决。

提要

  • 树的定义与相关概念
  • 二叉树的定义
  • 满二叉树与完全二叉树
  • 二叉树的性质
  • 二叉树的顺序存储结构
  • 二叉树的链式存储结构

树的定义与相关概念

树的示例:族谱

祖父
伯父
父亲
叔父
堂兄
堂姐
堂弟
侄儿

在这里插入图片描述
在这里插入图片描述

二叉树定义示例

R
A
B
C
D
E
F
G
null

完全二叉树与满二叉树示例

R
A
B
C
D
E
F
H
J
M
K
L
null

树的集合形式定义

  • Tree = (K, R)
    • 元素集合 K = {k_i | 0 ≤ i ≤ n, n ≥ 0, k_i ∈ ElemType}
    • n 为树中结点数,n=0 为空树,n>0 为非空树。
  • 对于一棵非空树,关系R满足下列条件:
    • 有且仅有一个结点没有前驱,称为根结点。
    • 除根结点外,其余每个结点有且仅有一个前驱。
    • 每个结点(包括根),可以有任意多个(含0个)后继 。
    • 在这里插入图片描述

树的递归形式定义

  • 树是由 n (n ≥ 0) 个元素构成的有限集合。
    • n=0 称为空树;n>0 称为非空树。
    • 非空树满足:
      • 有且仅有一个根结点。
      • 其余结点被分成 m (m ≥ 0) 个互不相交的有限集 T1, T2, …, Tm,每个 Ti 又是一颗树(递归)。
  • 树结构反映了元素间的层次关系,分类、分级的问题都可以考虑用树来描述。
  • 在这里插入图片描述

树的基本术语

  • 结点的度:结点所拥有子树的个数
  • 树的度:树中所有结点的度的最大值。
  • 叶结点:度为零的结点。
  • 分支结点:度不为零的结点。
  • 孩子结点和双亲结点:每个结点的后继被称作该结点的孩子结点,相应地,该结点被称作孩子结点的双亲结点
  • 兄弟结点:具有同一双亲的孩子结点。
  • 在这里插入图片描述
  • 结点的祖先:从根到该结点所经分支上的所有结点都称为该结点的祖先。
  • 结点的子孙:以某结点为的子树中的任一结点。
  • 结点的层次:树是一种层次结构,树中的每个结点都处于某个层次上。
  • 树的深度:树中所有结点层次的最大值,也称为树的高度
  • 有序树:树中各结点的子树是按照从左到右有序排列的,即各子树的位置不能交换。
  • 无序树:树中各结点的子树排列是无序的。
  • 森林:m(m≥0)颗互不相交的树的集合
    在这里插入图片描述

树的表示方法

  • 树形表示法:以圆圈表示结点,以连线表示结点之间的关系。

  • 在这里插入图片描述

  • 嵌套集合表示法:用圆圈表示树、子树和结点,并用包含关系表示结点间的关系。

  • 在这里插入图片描述

  • 凹入表示法:结点逐层缩进,孩子结点缩进于双亲结点。

  • 在这里插入图片描述

  • 广义表表示法:用广义表表示树,用名称表示树的根,括号内表示子树。

二叉树的定义

  • 二叉树:每个结点最多有两棵子树有序树
    • 二叉树或者是一棵空树,或者是一棵由一个根结点和两棵互不相交的分别称做根的左子树和右子树组成的非空树,左子树和右子树同样是一棵二叉树。
  • 注意:
    • 二叉树的度只能是0、1或2;
    • 二叉树是有序树,它的左、右子树是有次序的,即使只有一颗子树也要区分是左子树还是右子树。
    • 二叉树也是树,和树一样也有4种表示方法。
    • 在这里插入图片描述
  • 在这里插入图片描述

树的几种形态

形态1:一般的二叉树
左子树
右子树
左子树的左子树
左子树的右子树
右子树的左子树
右子树的右子树
形态2:只有左子树的二叉树
左子树
左子树的左子树
更深层次的左子树
形态3:只有右子树的二叉树
右子树
右子树的右子树
更深层次的右子树
形态4:完美二叉树(所有节点都有左右子节点)
左子树
右子树
左子树的左子树
左子树的右子树
右子树的左子树
右子树的右子树
左子树的左子树的左子树
左子树的左子树的右子树
左子树的右子树的左子树
左子树的右子树的右子树
右子树的左子树的左子树
右子树的左子树的右子树
右子树的右子树的左子树
右子树的右子树的右子树
形态5:完全二叉树(最后一层叶子从左到右填充)
左子树
右子树
左子树的左子树
左子树的右子树
右子树的左子树
右子树的左子树的左子树
右子树的左子树的右子树

满二叉树与完全二叉树

  • 满二叉树:二叉树的所有分支结点都有左子树和右子树,并且所有叶子结点都在二叉树的最下一层。(高度为h,且有2h-1个节点的二叉树)在这里插入图片描述

  • 完全二叉树:具有 n 个结点的完全二叉树,它的结构与满二叉树的前 n 个结点的结构相同

  • 在这里插入图片描述

二叉树的性质

  • 性质1:非空二叉树上的叶结点数等于双分支结点数加1。== n0 = n2 + 1==

    • 结点总数:n= n0 + n1 + n2 ……(1)
      n=6,n0=3,n1=1,n2=2,
    • 分支与结点的关系:B=n-1 ……(2)
      B=5,n=6,
    • 分支与结点度的关系:B=n1+2n2 ……(3)
      B=5, n1=1,2n2=4
      在这里插入图片描述
  • 性质2:非空二叉树的第 i (i≥1) 层上最多有 2^(i-1) 个结点。

    • 证明:使用归纳法。
      • 当i=1(第1层)时,只有根结点,即21-1=1,命题成立。
      • 当i>1(第 i 层)时,假定对于第i-1层命题成立,第i-1层最多有2(i-1)-1 =2i-2个结点。
      • 由于二叉树的每个结点最多有两个孩子结点,因此,第i层的结点总数最多是第i-1层结点数的2倍,即第i层最多有2×2i-2=2i-1个结点。
      • 命题得证。
  • 性质3:深度为 h (h≥1) 的非空二叉树最多有 2^h - 1 个结点。

    • 证明:只有满二叉树才能出现最多结点个数,即二叉树的每层结点数都应该达到最大结点数2i-1 。因此,深度为h的二叉树所具有的最多结点数为
    • 在这里插入图片描述
  • 性质4:具有 n (n>0) 个结点的完全二叉树的深度。

  • 在这里插入图片描述

  • 性质5:n 个结点的完全二叉树,按从上至下,从左至右的次序对结点编号,则编号为 i 的结点有以下性质。

    • 若编号为 i 的结点满足:i≤  n/2  ,即2i≤n,则该结点为分支结点,否则为叶子结点
    • 若n为奇数,则每个分支结点既有左孩子又有右孩子;
    • 若n为偶数,则编号最大的分支结点(编号为n/2)只有左孩子,没有右孩子,其余分支结点都有左、右孩子。
    • 在这里插入图片描述
    • 在这里插入图片描述
    • 若编号为i的结点有左孩子,则左孩子的编号为2i
    • 若编号为i的结点有右孩子,则右孩子的编号为2i+1
    • 除树根结点外,若一个结点的编号为i,则它的双亲结点的编号为 在这里插入图片描述
    • 在这里插入图片描述
    • 在这里插入图片描述

示例

已知一颗完全二叉树的第6层有7个结点,则:
该完全二叉树总共有多少个结点?
度为1的结点有多少个?

前5层为满二叉树,共有结点25-1=31,第6层7个结点,总结点数为31+7=38。
由于完全二叉树最后一层的结点必须从左至右连续出现,所以第6层的7个结点中,只有最后一个结点的双亲是度为1的结点,即度为1的结点有1个。

已知一颗完全二叉树的第6层有7个结点,则:
度为0的结点有多少个?
编号最大的非叶结点是哪一个?
编号最小的叶结点是哪一个?
由性质:若i≤  n/2  , 即2i≤n,则编号为i的结点为分支结点,否则为叶子结点。i=38/2=19,即从20到最后一个结点38之间都是叶子结点。度为0的结点有19个。
编号最大的非叶结点是最后一个结点的双亲  38/2  =19
编号最小的叶结点是编号最大的非叶结点的下一个结点,即20。

二叉树的顺序存储结构

  • 在一组连续的存储单元中,按照完全二叉树中结点编号将结点自上而下、自左至右的顺序存储。
    元素的位置序号和结点的编号相对应,即结点在数组中的位置表示了结点之间的关系:
    结点编号为 i,则:
    结点i的双亲结点  i/2 
    结点i的左子结点 2i,右子结点 2i+1
    在这里插入图片描述
    在这里插入图片描述

非完全二叉树的存储方法

在这里插入图片描述
在这里插入图片描述

顺序存储结构示例

对于完全二叉树的顺序存储,

左子结点
右子结点
左子结点
右子结点
左子结点
右子结点
根结点
A
B
C
D
E
F
G
H

二叉树的链式存储结构

  • 一个二叉链表由根指针 root 唯一确定。
  • 若二叉树为空,则 root=NULL;若结点的某个孩子不存在,则相应的指针为空。
    在这里插入图片描述

结点类型

typedef struct node {
    ElemType data; // 数据域
    struct node *left;
    struct node *right; // 结点的左右子树指针
} BTNode; // 二叉树结点类型

一个二叉链表由根指针root唯一确定。
若二叉树为空,则root=NULL;
若结点的某个孩子不存在,则相应的指针为空。

逻辑关系与链式存储结构

  • 根据实际问题的需要,还可以在结点中添加指向父结点的指针。

链式存储结构示例

链式存储通常使用指针或引用来连接节点。在Mermaid中,我们可以用箭头来表示这种连接:

左子结点
右子结点
左子结点
右子结点
左子结点
右子结点
A
C
B
D
E
F
G

三叉链表

根据实际问题的需要,还可以在结点中添加指向父结点的指针。
在这里插入图片描述

struct node {
    ElemType data;
    struct node *left;
    struct node *right;
    struct node *parent; // 指向父结点的指针
};

总结

  • 树的定义与相关概念
  • 二叉树的定义
  • 满二叉树与完全二叉树
  • 二叉树的性质
  • 二叉树的顺序存储结构
  • 二叉树的链式存储结构
  • 24
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值