美文网首页
数据结构与算法基础五:树

数据结构与算法基础五:树

作者: Trigger_o | 来源:发表于2021-05-20 17:12 被阅读0次

    一:树

    1.定义
    树是n个节点的有限集,n=0称为空树,非空树满足这样两个条件:
    1.只有一个根节点
    2.其余节点可以分为有限个互不相交的有限集,每个集合也都是数.


    子树

    2.节点

    • 定义:树的节点包括数据元素以及子树分支,节点拥有的子树个数叫做节点的度,度=0的节点叫做叶节点(终端节点),度不等于0的节点叫做分支节点(非终端节点),除根节点之外还可以叫做内部节点,树的度是节点中度的最大值,上图节点的度最大值是3,因此树的度是3.

    • 关系:节点的子树的根节点,叫做子节点(child),反过来叫做父节点(parent),同一个父节点(双亲节点)的叫做兄弟节点(sibling)

    3.其他概念

    • 深度:从根节点向子节点,叫做数的层次(level),根节点是第一层,或者说深度是1.
    • 有序:如果节点的子树从左到右是固定不能变动的,那么该树成为有序树,否则是无序树.
    • 森林:Forest是互不相交的树的有限集,因此一个树的两个子树,也可以看做森林.
    线性表与树

    二:树的存储

    1.双亲表示法
    在一段连续的内存空间存储树的节点,每个节点存储数据(data),并且存储父节点的下标(parent),根节点的parent为-1.

    双亲表示法
    这种结构查找父节点很直接,复杂度是O(1),但是如果要找子节点,就得遍历.

    如果把子节点的下标也存储呢.把最左边的子节点叫做长子,把它的下标也记录在节点内:


    image.png

    这样,节点可以找到长子节点,对于度在3以内的树来说,就可以满足了.
    但是如果是一个非常关注兄弟之间关系的结构,就不行了,这时候可以再增加一个右兄弟域,来存储右边兄弟节点的下标.

    2.孩子表示法
    用多重链表来存储树:链表的节点含有一个指针域或两个指针域,指向相邻的节点.现在给节点增加更多的指针域,指向子节点.

    第一种方法,可以把树的度作为指针域的个数,但是对于节点的度区别很大的树,这会造成空间上的浪费,但是省去了灵活配置需要的运算,算是用空间换时间.


    data是数据,后面全都是子节点的指针域
    显然会有很多空间浪费

    第二种方法,灵活配置每个节点的指针域个数,使其等于节点的度,这个时候度作为关键信息需要被存在节点内,增加了一个degree,度域.这种方法维护节点变得更加复杂,用时间换空间.


    data是数据,degree是度域,后面全都是子节点的指针域
    空间利用合理

    如何同时解决上面两个问题,现在引出孩子表示法:
    首先把每个节点的子节点组织成一个链表,叫做孩子链表,有n个节点,就有n个孩子链表,叶节点的孩子链表是空链表;
    然后再讲这些链表的头指针顺序存储,存储单元分为数据域和指针域,指针域存的就是孩子链表的头指针.


    孩子表示法

    其中:孩子链表的元素分为节点域和next指针,节点是指数据在数组中的下标,next执行兄弟节点的元素;


    孩子链表的元素结构
    节点表的元素结构
    这种结构下,想查找子节点,遍历孩子链表就行了,如果想遍历数,直接遍历节点表就行了,但是这也有问题,那就是查找父节点很麻烦.

    3.孩子兄弟表示法
    前面从父节点和子节点的角度分析,现在从兄弟节点的角度进行分析.
    构建一个节点,分为数据域和两个指针域,一个指向第一个子节点,另一个指向自己的兄弟节点.

    data+子节点+兄弟节点
    用这个结构描述所有的节点,根节点兄弟指针域是空的,叶节点的子节点指针域是空的.如果需要查找父节点,那就再增加一个父节点指针域.
    孩子兄弟表示法
    可以看到它又构成了一个树形结构,而且这个数的度一定是2,这种方法的优势就是把复杂的树改造成了二叉树,便于利用二叉树的性质.
    变成了二叉树

    相关文章

      网友评论

          本文标题:数据结构与算法基础五:树

          本文链接:https://www.haomeiwen.com/subject/kxdprltx.html