【树】树、森林和二叉树的关系

树的存储结构
1.双亲表示法
  • 这种方法用一组连续的空间来存储树中的结点,在保存每个结点的同时附设一个指示器来指示其双亲结点在表中的位置,其结点的结构如下图所示:

在这里插入图片描述

双亲表示法的形式说明如下:

#define MAX 100
typedef struct TNode
{
  DataType data;
  int parent;
} TNode;

树可以定义为:

typedef struct
{
  TNode tree[MAX];
  int nodenum; /*结点数*/
} ParentTree;

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

2.孩子表示法
  • 这种方法通常是把每个结点的孩子结点排列起来,构成一个单链表,称为孩子链表。n 个结点共有 n 个孩子链表(叶子结点的孩子链表为空表),而 n 个结点的数据和 n 个孩子链表的头指针又组成一个顺序表。

在这里插入图片描述

孩子表示法的存储结构定义如下:

typedef struct ChildNode /* 孩子链表结点的定义 */
{
  int Child;              /* 该孩子结点在线性表中的位置 */
  struct ChildNode *next; /*指向下一个孩子结点的指针 */
} ChildNode;
typedef struct /* 顺序表结点的结构定义 */
{
  DataType data;         /* 结点的信息 */
  ChildNode *FirstChild; /* 指向孩子链表的头指针 */
} DataNode;
typedef struct /* 树的定义 */
{
  DataNode nodes[MAX]; /* 顺序表 */
  int root;            /* 该树的根结点在线性表中的位置 */
  int num;             /* 该树的结点个数 */
} ChildTree;
3.孩子兄弟表示法(最重要)
  • 这种表示法又称为树的二叉表示法,或者二叉链表表示法,即以二叉链表作为树的存储结构。链表中每个结点设有两个链域,分别指向该结点的第一个孩子结点和下一个兄弟(右兄弟)结点。

在这里插入图片描述

孩子兄弟表示法的类型定义如下:

typedef struct CSNode
{
  DataType data;              /*结点信息*/
  Struct CSNode *FirstChild;  /*第一个孩子*/
  Struct CSNode *Nextsibling; /*下一个兄弟*/
} CSNode, *CSTree;

这种存储结构便于实现树的各种操作,例如,如果要访问结点 x 的第 i 个孩子,则只要先从FirstChild 域找到第一个孩子结点,然后沿着这个孩子结点的 Nextsibling 域连续走 i-1 步,便可找到 x的第 i 个孩子。如果在这种结构中为每个结点增设一个 Parent 域,则同样可以方便地实现查找双亲的操作。

树、森林与二叉树的相互转换

前面介绍了树的存储结构和二叉树的存储结构,从中可以看到,树的孩子兄弟链表结构与二叉树的二叉链表结构在物理结构上是完全相同的,只是它们的逻辑含义不同,所以树和森林与二叉树之间必然有着密切的关系。本节介绍树和森林与二叉树之间的相互转换方法。

1.树转换为二叉树

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

2.森林转换为二叉树
  • 森林是若干棵树的集合。树可以转换为二叉树,森林同样也可以转换为二叉树。因此,森林也可以方便地用孩子兄弟链表表示。

在这里插入图片描述

3.二叉树还原为树或森林

在这里插入图片描述

树与森林的遍历
1.树的遍历

在这里插入图片描述
在这里插入图片描述
方法一:

void RootFirst(CSTree root)
{
  if (root != NULL)
  {
    Visit(root->data); /* 访问根结点 */
    p = root->FirstChild;
    while (p != NULL)
    {
      RootFirst(p); /* 访问以 p 为根的子树 */
      p = p->Nextsibling;
    }
  }
}

方法二:

void RootFirst(CSTree root)
{
  if (root != NULL)
  {
    Visit(root->data);            /*访问根结点*/
    RootFirst(root->FirstChild);  /*先根遍历首子树*/
    RootFirst(root->Nextsibling); /*先根遍历兄弟树*/
  }
}
2.森林的遍历

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
例如,右图中森林的后序遍历序列为 DCBFJIHGEA。
在这里插入图片描述

对照二叉树与森林之间的转换关系可以发现,森林的先序遍历、中序遍历和后序遍历与其相应二叉树的先序遍历、中序遍历和后序遍历是对应相同的,因此可以用相应二叉树的遍历结果来验证森林的遍历结果。另外,树可以看成只有一棵树的森林,所以树的先根遍历和后根遍历分别与森林的先序遍历和中序遍历对应。森林的遍历算法可以采用其对应的二叉树的遍历算法来实现。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值