存储
先讨论一般树
- 双亲表示法(数组结构存储)
- 孩子表示法(邻接表结构存储)
- 孩子兄弟表示法(转换成二叉树存储)
在一一介绍之前,想要说的是不论哪一种方法,我们都要先知道要干什么,然后选择方法。
双亲表示法
结构体数组,按照按行遍历的结果放在数组中,并且记录每一个结点的双亲结点是哪个(除了根节点),还是数组第一位不存储信息

T[3].data=‘C’
T[3].parent=T[1].data=A
这样的结构有利于寻找双亲结点,如果是一个需要回溯的过程,双亲表示法是一个不错的选择
孩子表示法
说有这么一个树哈:

邻接表:说白了就是纵向数组存储结点,横向用指针连接孩子。

可能有时候需要双亲结点,这样又不是很方便,所以呢我们在结构体数组加一项,储存双亲的下标

孩子兄弟表示法
这个有一点不好阐述,直接上图:
一棵树:

将同一个双亲的孩子们连接上,只留下第一个孩子和双亲结点连接;

得到的就是一个二叉树,可能不太好看,稍微拉伸一下:

此时得到的二叉树,左孩子上都是孩子,右孩子上是曾经的兄弟
(我本把你当兄弟,你却要叫我爸爸)
在这里就要拓展一个二叉树的存储结构了,利用结构体数组:
struct Btree*
{
int data;
int lchild,rchild;
}
没错,这里为什么用int型呢?应当想到的是数组的下标。

这样就实现了二叉树的存储,要是不行也可以学习邻接表的方式,加一排双亲结点下标。
接下来就是森林的存储了:

这样的一个森林,先对每一个树转化成二叉树:

接下来拼接二叉树就行了:

得,兄弟又变成孩子了(doge)
遍历
对于一般树和森林,因为子树棵数的不确定,所以我们就约定将一棵树分解成三部分:
根节点、最左子树、其余的子树
这三部分对应了原来二叉树的根节点、左子树和右子树,剩下的都是相同的。
但同时,树也可以转化成二叉树来遍历,那么他们之间应该有什么关系的吧?
刚才的例子:

对于二叉树,先序位根左右,而这里的二叉树是左孩子右兄弟,所以就是先根,然后第一颗子树,然后剩下的子树,正好位树的遍历。
而二叉树的中序是左根右,先孩子,然后是根节点,然后是右孩子,但是这里有一个细节,根节点是没有右孩子的,所以根节点的输出在最后,和对应树的后序相同。
森林也是相似的操作,不过是对从左到右的每一个树都做相同的操作就是了。
228

被折叠的 条评论
为什么被折叠?



