《大话数据结构》笔记——第6章 树(一)

声明:

本博客是本人在学习《大话数据结构》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。

本博客已标明出处,如有侵权请告知,马上删除。

6.1 开场白

6.2 树的定义

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

树(Tree)是 n(n>=0)个结点的有限集。

n=0 时称为空树。

在任意一棵非空树中:

(1)有且仅有一个特定的称为根(root)的结点。

(2)当 n>1 时,其余结点可以分为 m(m>0)个互不相交的有限集 T1,T2,T3……Tm,其中每个集合本身又是一棵树,并且称为根的子树(SubTree)

如图 6-2-1 所示

在这里插入图片描述

树的定义其实就是我们在讲解栈时提到的递归的方法。也就是在树的定义之中还用到了树的概念,这是一种比较新的定义方法。图 6-2-2 的子树 T1 和子树 T2 就是根结点 A 的子树。当然,D、G、H、I 组成的树又是 B 为结点的子树,E、J 组成的树是 C 为结点的子树。

在这里插入图片描述

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

  1. n>0 时根结点是唯一的,不可能存在多个根结点,别和现实中的大树混在一起,现实中的树有很多根须,那是真实的树,数据结构中的树只能有一个根结点。

  2. m>0 时,子树的个数没有限制,但它们一定是互不相交的。像图 6-2-3 中的两个结构就不符合树的定义。因为它们都有相交的子树。

    在这里插入图片描述

6.2.1 结点分类

树的结点包含一个数据元素及若干个指向其子树的分支。结点拥有的子树数称为结点的度(Degree)。度为 0 的结点称为叶结点(Leaf)或终端结点;度不为 0 的结点称为非终端结点或分支结点。除根结点之外,分支结点也称为内部结点。树的度是树内各结点的度的最大值。如图 6-2-4 所示,因为这棵树结点的度的最大值是结点 D 的度,为 3,所以树的度也为 3。

在这里插入图片描述

6.2.2 结点间关系

结点的子树的根称为该结点的孩子(Child)。相应地,该结点称为孩子的双亲(Parent)。嗯,为什么不是父或母,叫双亲呢?呵呵,对于结点来说其父母同体,唯一的一个,所以只能把它称为双亲了。同一个双亲的孩子之间互称兄弟(Sibling)。结点的祖先是从根到该结点所经分支上的所有结点。所以对于 H 来说,D、B、A 都是它的祖先。反之,以某结点为跟的子树的任一结点都称为该结点的子孙。B 的子孙有 D、G、H、I,如图 6-2-5 所示。

在这里插入图片描述

6.2.3 树的其他相关概念

结点的层次(Level)从根开始定义起,根为第一层,根的孩子为第二层。若某结点在第 l 层,则其子树的根就在第 l+1层。其双亲在同一层的结点互为堂兄弟。显然图 6-2-6 中的 D、E、F 是堂兄弟,而 G、H、I、J 也是。树中结点的最大层次称为树的深度(Depth)或高度,当前树的深度为 4。

在这里插入图片描述

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

森林(Forest)是 m(m>=0)棵互不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。对于图 6-2-1 中的树而言,图 6-2-2 中的两棵子树其实就可以理解为森林。

对比线性表与树的结构,它们有很大的不同,如图 6-2-7 所示。

在这里插入图片描述

6.3 树的抽象数据类型

相对于线性结构,树的操作就完全不同了,这里我们给出一些基本和常用操作。

ADT 树(tree)
Data 
    树是由一个根结点和若干课子树构成。树中结点具有相同数据类型及层次关系。
Operation
    InitTree(*T):构成空树 T。
    DestroyTree(*T):销毁树 T。
    CreateTree(*T,Definition):按 definition 中给出的树的定义来构造树。
    ClearTree(*T):若树 T 存在,则将树 T 清为空树。
    TreeEmpty(T):若 T 为空树,返回 true,否则返回 false。
    TreeDepth(T):返回 T 的深度。
    Root(T):返回 T 的根结点。
    Value(T,cur_e):cur_e 是树T中一个结点,返回此结点的值。
    Assign(T,cur_e,value):给树 T 的结点 cur_e 赋值为 value。
    Parent(T,cur_e):若 cur_e 是树 T 的非根结点,则返回它的双亲,否则返回空。
    LeftChild(T,cur_e):若 cur_e 是树 T 的非叶结点,否则返回它的最左孩子,否则返回空。
    RightSlibling(T,cur_e):若 cur_e 有右兄弟,则返回它的右兄弟,否则返回空。
    InsertChild(*T,*p,i,c):其中 p 指向树 T 的某个结点,i 为所指结点 p 的度加上 1,
        非空树 c 与 T 不相交,操作结果为插入 c 为树 T 中 p 指结点的第 i 棵子树。
    DeleteChild(*T,*p,i):其中 p 指向树 T 的某个结点,i 为所指结点 p 的度,
        操作结果为删除 T 中 p 所指结点的第 i 棵子树。
endADT

6.4 树的存储结构

6.4.1 双亲表示法

树这种结构,除了根结点外,其余每个结点,它不一定有孩子,但是一定有且仅有一个双亲。

我们假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。也就是说,每个结点除了知道自己是谁以外,还知道它的双亲在哪里。它的结点结构为表 6-4-1 所示。

在这里插入图片描述

其中 data 是数据域,存储结点的数据信息。而 parent 是指针域,存储该结点的双亲在数组中的下标

以下是我们的双亲表示法的结点结构

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值