树的存储结构

1,240 阅读4分钟

顺序存储结构

充分利用顺序存储结构和链式存储结构

  • 双亲表示法

    1. 定义:以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点在数组中的位置(也就是说除了知道自己是谁以外,还知道她的双亲在哪里)
    2. 表示方法:
    • 双亲域

      域名 中文 作用
      data 数据域 存储结点的数据信息
      parent 指针域 存储该结点的双亲在数组中的下标

      作用:根据parent指针很容易找到他的双亲结点,直到parent为-1时,表示找到了树结点的根。

    • 长子域(最左边的结点)

    域名 中文 作用
    data 数据域 存储结点的数据信息
    parent 指针域 存储该结点的双亲在数组中的下标
    firstchild 长子域 可以得到最左边的孩子结点,若没有孩子的结点,这个长子域就设置为-1

    作用:对于有0个或者1个孩子结点来说,这样的结构是为要找结点孩子的问题,甚至有两个孩子时,知道了长子是谁,另一个便是次子。

    • 右兄弟域

      域名 中文 作用
      data 数据域 存储结点的数据信息
      parent 指针域 存储该结点的双亲在数组中的下标
      rightsib 右兄弟域 每一个节点如果存在右兄弟,则记录下有兄弟的下标,如果没有右兄弟,则赋值为-1

      作用:为了了解该结点是否有兄弟节点。

  • 孩子表示法(链表法)

  1. 多重链表表示法 :每个结点有多个指针域,其中每个指针指向一棵子树的根节点

    方案一 :

方案一

域名 中文 作用
data 数据域 存储数据
child1~childd 指针域 用来指向该结点的孩子结点

方案二

域名 中文 作用
data 数据域 存储数据
child1~childd 指针域 用来指向该结点的孩子结点
degree 度域 存储该结点的孩子结点的个数
孩子表示法

把每个节点的孩子结点排列起来,以单链表做存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针又组成一个线性表,采用顺序存储结构,存放一个一位数组中。

两种结点结构:

表示孩子链表的孩子结点

域名 中文 作用
child 数据域 用来存储某个节点在表头数组中的下标
next 指针域 用来存储指向某结点的下一个孩子结点的指针

表示表头数组的表头节点

域名 中文 作用
data 数据域 存储某结点的数据信息
firstchild 头指针域 存储该结点的孩子链表的头指针

作用:

  1. 这样的结构对于我们要查找某个结点的某个孩子,或者找某个结点的兄弟,只需要查找这个结点的孩子单链表即可。
  2. 对于遍历整棵树也很方便的,对头结点的数组循环即可。

存在问题:

  1. 不知道某个结点的双亲。

修改之后:双亲孩子表示法(双亲表示法和孩子表示法综合一下)

域名 中文 作用
parent 数据域 存储某结点的双亲结点的数据信息,如果没有双亲结点则为 -1
  • 孩子兄弟表示法

    规律:任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟

    结点结构如图1:

域名 中文 作用
data 数据域 存储某结点的数据信息
firstchild 指针域 存储该结点的第一个孩子结点的存储地址
rightsib 指针域 存储该结点的右兄弟结点的存储地址

作用:

  1. 给查找某个结点的某个孩子带来了方便,只需要通过firstchild找到此结点的长子,然后再通过长子结点的rightsib找到他的二弟,接着一直找下去,直到找到具体的孩子。
  2. 把一棵复杂的树便成了一棵二叉树。

缺陷: 不能找某个结点的双亲。

修改之后: