树与森林

发布时间 2023-03-23 16:02:51作者: 青子Aozaki

逻辑结构

n个结点的有限集。
在任意一棵树应满足:

  1. 有且仅有一个结点称为根结点
  2. n>1时,其余结点可分为m个互不相交的有限集,其中每个集合又是一棵树

树的定义是递归的。

特点

  • 树的根结点没有前驱,除此之外,所有结点有且只有一个前驱。
  • 树中所有结点可以有0个或多个后继。

概念

  1. 根A到结点K的唯一路径上的任意结点,称为结点K的祖先。结点K是这些结点的子孙。最接近结点K的结点称为双亲,结点K是它的孩子
  2. 树中一个结点的孩子个数称为该结点的。树中结点的最大度数称为树的度
  3. 度>0的结点称为分支节点(非终端结点),度=0的结点称为叶子结点(终端结点)
  4. 根结点为第一层,子节点为第二层......在同一层的结点互为堂兄弟。
  5. 结点的深度是从根结点自顶向下逐层累加的。
  6. 结点的高度是从叶节点自底向上逐层累加的。
  7. 树的高度(或深度)是树中结点的最大层数。
  8. 树中各结点的子树从左到右都是有次序的,不能互换,称为有序树
  9. 路径是两个结点之间的结点序列,路径长度是路径上所经过的边的个数。

由于树中的分支是有向的(从双亲指向孩子),所以树中的路径是从上到下的。
堂兄弟之间不存在路径

  1. 互不相交的树的集合,称为森林

只要把树的根节点去掉,就成了森林。
反之,森林中的多个树加上根结点,他们就成了同一颗树。

性质

  • 树中的结点数 = 所有结点的度数和+1(根结点)
  • 度为m的树中第i层上至多有mi-1个结点
  • 高度为h的m叉树至多有(mh-1)/(m-1)个结点
  • 具有n个结点的m叉树的最小高度为logm(n(m-1)+1)

第一条性质换言之,在n个结点的树中有n–1条边。如若森林有15条边,25个结点,则该森林包含树的个数为10(25-15=10)

物理结构

双亲表示法

用一组连续的地址空间,存储每个结点,结点中增设一个伪指针,指示其双亲结点在数组中的位置。

  • 得到双亲结点:O(1)
  • 得到子结点:O(n)

孩子表示法

将每个结点的孩子结点都用单链表链接起来形成一个线性结构。

  • 得到子节点:O(1)
  • 得到双亲结点:O(n)

孩子兄弟表示法

又称为二叉树表示法。
每个结点包括:数据域、指向结点第一个孩子的指针、指向结点下一个兄弟的指针。
可以方便地实现树转化为二叉树的操作。

  • 得到子节点:O(1)
  • 得到双亲结点:O(n)

树的基本操作

树转化为二叉树:

  1. 在兄弟结点之间添加一条线
  2. 对于每个结点,只保留它与第一个孩子的连线,与其他孩子的连线全部抹掉
  3. 以树根为轴心,顺时针旋转45°

先根遍历

若树非空,先访问根结点,再依次访问根结点的每棵子树,遍历子树时仍遵循先根后子树的原则。(与二叉树的先序遍历相同)

后根遍历

若树非空,先依次遍历根结点的每棵子树,再访问根结点,遍历子树时仍遵循先子树后根的原则。(与二叉树的中序遍历相同,因为树转化为二叉树后根结点是没有右子树的)

森林的基本操作

森林转化为二叉树:

  1. 将森林中的每棵树转化为二叉树
  2. 每棵树的根视为兄弟关系,在各树的根之前加一条连线
  3. 以第一棵树的根为轴心顺时针旋转45°

二叉树转化为森林:

  1. 将根的右链断开,根的右子树又可视为除第一棵树外的森林转换后的二叉树
  2. 重复1.直至只剩一棵没有右子树的二叉树为止
  3. 将每棵二叉树依次转换成树,就得到了原森林

二叉树转为树或森林是唯一的

先序遍历森林

若森林非空,先访问森林中第一棵树的根结点,然后先序遍历第一棵树根结点的子树森林,之后先序遍历除第一棵树外剩余的树构成的森林。

中序遍历森林(后根遍历森林)

若森林非空,先中序遍历森林中第一棵树的根结点的子树森林,然后访问第一棵树的根结点,之后中序遍历除第一棵树外剩余的树构成的森林。

当森林转换为二叉树时,第一棵树的子树森林转化为左子树,剩余树的森林转化为右子树。
所以森林的先序遍历与中序遍历对应二叉树的先序遍历和中序遍历。

树与森林的遍历与二叉树遍历的对应关系:

森林 二叉树
先根遍历 先序遍历 先序遍历
后根遍历 中序遍历 中序遍历

应用

并查集

通常用树(或森林)的双亲表示作为并查集的存储结构。
每个子集用一棵树表示,所有表示子集和的树,构成表示全集合的森林,存放在双亲表示数组内。
并运算(U)时,将其中一个子集和的根结点的双亲结点指向另一个集合的根结点。
判断两个元素是否属于同一集合,只需要分别找到它们的根结点,比较根结点是否相同即可。