树与二叉树、森林
首先我们来介绍一种树节点的表示法:
举个例子:
如下图:
A 的左指针指向长子(左孩子)B,右指针指向相邻兄弟,显然 无 。
B左指针指向向长子(左孩子)D,右指针指向相邻兄弟,显然是C。
C左指针指向向长子(左孩子)G,右指针指向相邻兄弟,显然 无 。
D左指针指向向长子(左孩子)无,右指针指向相邻兄弟,显然是E。
E左指针指向向长子(左孩子)无,右指针指向相邻兄弟,显然是F。
由 “孩子兄弟表示法” 知,树与二叉树均可用二叉链表作为存储结构,那么就可以用 二叉链表来作为“媒婆”(不好意思,“媒介”)导出树与二叉树之间的对应关系。
【注】: 树转换为二叉树时,其左、右子树的概念已改变为:左-->孩子,右-->兄弟
举例:
-
树-------->二叉树:
转化三部曲:
1.加线 : 树中所有相邻兄弟之间加一条连线(处于同一层且双亲相同的节点叫兄弟)
2.删线 : 每个节点仅保留长子(左孩子),删去与其他孩子之间的连线
3.旋转 :以第一棵树的根节点作为转化后的大二叉树的根节点,然后按照一定的角度进行旋转即可。
![](https://img-blog.csdnimg.cn/20190820175204889.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MTkzODgz,size_16,color_FFFFFF,t_70)
-
森林----->二叉树:
转化三部曲:
1.加线 : 树中所有相邻兄弟之间加一条连线(处于同一层且双亲相同的节点叫兄弟,各棵树根节点也视为兄弟)
2.删线 : 每个节点仅保留长子(左孩子),删去与其他孩子之间的连线
3.旋转 :以第一棵树的根节点作为转化后的大二叉树的根节点,然后按照一定的角度进行旋转即可。
![](https://img-blog.csdnimg.cn/20190820175321599.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MTkzODgz,size_16,color_FFFFFF,t_70)
-
二叉树---->树:
转化三部曲:
1.加线 :把根节点与其左子树的右子树,左子树的右子树的右子树......等都加线
2.删线 : 每个节点仅保留长子(左孩子),删去与其右孩子之间的连线
3.旋转 :按照一定的角度进行旋转即可。
-
二叉树--->森林:
转化三部曲:
1.加线 :把根节点与其左子树的右子树,左子树的右子树的右子树......等都加线
2.删线 : 每个节点仅保留长子(左孩子),删去与其右孩子之间的连线
3.旋转 :按照一定的角度进行旋转即可。
-
树与二叉树的遍历:
如下图:
树的先根遍历序列为:A B E C F H G D <-------对应于------->二叉树的先根遍历序列:A B E C F H G D
树的后根遍历序列为:E B H F G C D A <-------对应于------->二叉树的中序遍历序列:E B H F G C D A
-
森林与二叉树的遍历:
1. 森林的先序遍历 步骤:
a.访问森林第一棵树的根结点;
b.先序遍历森林第一棵树根结点的子树森林;
c.先序遍历除第一棵树之外其余树构成的森林。
2. 森林的中序遍历 步骤:
a.中序遍历森林第一棵树根结点的子树森林;
b.访问森林第一棵树的根结点;
c.中序遍历除第一棵树之外其余树构成的森林。
举例说明:
如下图:
森林的先根遍历序列为:A B C D E F G H I J <-------对应于------->二叉树的先根遍历序列:A B C D E F G H I J
森林的中序遍历序列为:B C D A F E H J I G <-------对应于------->二叉树的中序遍历序列:B C D A F E H J I G
-
树与森林的算法:
【注】只需将树与森林转化为二叉树的存储结构即可
typedef char Elemtype;
//定义 树、森林的存储结构
typedef struct Tnode{
Elemtype data;
struct Tnode *Fchild,*Nextb;
}Tnode,*Tree;
其他相应操作类似二叉树的,只不过是左右指针域指示的对象不同而已。
二叉树相关操作: https://blog.csdn.net/qq_38193883/article/details/98872803
-
正经致谢: