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

原文:http://jpkc.nwu.edu.cn/sjjg/study_online/book/6/4_2.htm

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

1.树转换为二叉树

对于一棵无序树,树中结点的各孩子的次序是无关紧要的,而二叉树中结点的左、右孩子结点是有区别的。为了避免混淆,我们约定树中每一个结点的孩子结点按从左到右的次序顺序编号,也就是说,把树作为有序树看待。如图6.21所示的一棵树,根结点A有三个孩子B、C、D,可以认为结点B为A的第一个孩子结点,结点D为A的第三个孩子结点。

将一棵树转换为二叉树的方法是:

⑴ 树中所有相邻兄弟之间加一条连线。

⑵ 对树中的每个结点,只保留其与第一个孩子结点之间的连线,删去其与其它孩子结点之间的连线。 

⑶ 以树的根结点为轴心,将整棵树顺时针旋转一定的角度,使之结构层次分明。

可以证明,树做这样的转换所构成的二叉树是唯一的。图6.22给出了将图6.21所示的树转换为二叉树的转换过程示意。

通过转换过程可以看出,树中的任意一个结点都对应于二叉树中的一个结点。树中某结点的第一个孩子在二叉树中是相应结点的左孩子,树中某结点的右兄弟结点在二叉树中是相应结点的右孩子。也就是说,在二叉树中,左分支上的各结点在原来的树中是父子关系,而右分支上的各结点在原来的树中是兄弟关系。由于树的根结点没有兄弟,所以变换后的二叉树的根结点的右孩子必然为空。

 
 

事实上,一棵树采用孩子兄弟表示法所建立的存储结构与它所对应的二叉树的二叉链表存储结构是完全相同的,只是两个指针域的名称及解释不同而已,通过图6.23直观的表示了树与二叉树之间的对应关系和相互转换方法.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


因此,二叉链表的有关处理算法可以很方便地转换为树的孩子兄弟链表的处理算法。

 

2.森林转换为二叉树

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

(1)      将森林中的每棵树转换成相应的二叉树。

(2)      第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树根结点的右孩子,当所有二叉树连在一起后,所得到的二叉树就是由森林转换得到的二叉树。

图6.24给出了森林及其转换为二叉树的过程。

我们还可以用递归的方法描述上述转换过程:

将森林F看作树的有序集F={T1,T2,…,TN},它对应的二叉树为B(F):

(1)若N=0,则B(F)为空。

(2)若N>0,二叉树B(F)的根为森林中第一棵树T1的根; B(F)的左子树为B({T11,…,T1m}),其中{T11,…,T1m}是T1的子树森林;B(F)的右子树是B({T2,…,TN})。

根据这个递归的定义,我们可以很容易地写出递归的转换算法。

 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


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

树和森林都可以转换为二叉树,二者的不同是:树转换成的二叉树,其根结点必然无右孩子,而森林转换后的二叉树,其根结点有右孩子。将一棵二叉树还原为树或森林,具体方法如下:

(1) 若某结点是其双亲的左孩子,则把该结点的右孩子、右孩子的右孩子、……都与该结点的双亲结点用线连起来。

(2) 删掉原二叉树中所有双亲结点与右孩子结点的连线。

(3) 整理由(1)、(2)两步所得到的树或森林,使之结构层次分明。

图6.25为一棵二叉树还原为树的过程示意图。

 

 

 

 

 

 

 

 

 

 

 


同样,我们可以用递归的方法描述上述转换过程。

若B是一棵二叉树,T是B的根结点,L是B的左子树,R为B的右子树,且B对应的森林F(B)中含有的n棵树为T1,T2, …,Tn,则有:

(1)  B为空,则F(B)为空的森林(n=0)。

(2)  B非空,则F(B)中第一棵树T1的根为二叉树B的根T;T1中根结点的子树森林由B的左子树L转换而成,即F(L)={T11,…,T1m};B的右子树R转换为F(B)中其余树组成的森林,即F(R)={ T2, T3,…,Tn}。

根据这个递归的定义,我们同样可以写出递归的转换算法。

 


你可能感兴趣的:(数据结构)