树和森林

1.树的存储结构

      树的存储方式有很多,既可以采用顺序存储,也可采用链式存储,不管采用哪种方式,都需要唯一地反映出树中各节点之间的逻辑关系,树有以下3中常用的存储结构。

1.1 双亲表示法

      使用一组连续的空间存储每个结点,同时增加一个伪指针,指示其双亲结点在数组中的位置,如图所示,根节点下标为0,伪指针域为-1。

 

      这种存储方式,利用了每个结点只有唯一双亲的性质(除根结点)。求结点的双亲结点很快,但求其孩子结点必须遍历整个结构。

1.2 孩子表示法

      将每个结点的孩子结点都用单链表链接起来形成一个线性结构,则N个结点就有N个    孩子链表(叶子结点的孩子链为空表),如下图所示,

 

      这种存储方式寻找子女很方便,寻找双亲需要遍历N个结点中孩子链表指针域所指向的N个孩子链表。

1.3 孩子兄弟表示法

      又称为二叉树表示法,即以二叉链表作为树的存储结构。每个结点包含三部分内容:结点值,指向结点第一个孩子结点的指针和指向结点下一个兄弟结点的指针(沿此域可找到结点所有兄弟结点),如图所示,

 

      这种存储方式比较灵活,最大的优点就是可以方便的实现树转换为二叉树,易于查找结点的孩子等,缺点是从当前结点查找双亲结点比较麻烦,可以为每个结点增加一个parent域指向其父节点。

2.树、森林与二叉树的转换

2.1 树转换为二叉树

      从物理结构来看,树的孩子兄弟表示法和二叉树的二叉链表表示法相同,都有两个指针,树是一个指向结点的第一个孩子,一个指向结点的下一个兄弟结点;二叉树分别指向左孩子和右孩子。因此就可以用同一存储结构的不同解释将一颗树转换为二叉树。

      树转换为二叉树的规则:每个结点左指针指向它的第一个孩子结点,右指针指向它在树中相邻兄弟结点,可表示为“左孩子右兄弟”。由于根节点没有兄弟,所以,树转换而得到的二叉树没有右子树,如图:

 

2.2 森林转换为二叉树

      将森林转换为二叉树的规则与树类似,先将森林中的每一棵树转换为二叉树(没有右子树的二叉树),再将第一棵树的根作为转换后的二叉树的根,第一棵树的左子树作为转换后二叉树的左子树,第二棵树作为转换后二叉树的右子树,第三棵树作为转换后二叉树根的右子树的右子树,以此类推。

      二叉树转换为森林的规则:若二叉树非空,则二叉树根及其左子树为第一棵树的二叉树形式,二叉树根的右子树又可以看做是一个由除第一棵树外的森林转换后的二叉树,应用同样的方法,直到最后产生一颗没有右子树的二叉树为止,这样就得到了原森林。二叉树转树规则类似,二叉树转换为树或森林是唯一的。如图:

 

3.树和森林的遍历

树的遍历操作主要有先根遍历和后根遍历。

(1)先根遍历:若树非空,则先访问根结点,在按从左到右的顺序遍历根结点的每一棵子树,访问顺序与这棵树相应二叉树的先序遍历顺序相同。

(2)后根遍历:若树非空,则按从左到右的顺序遍历根结点的每一棵子树,之后再访问根结点,访问顺序与这棵树相应二叉树的中序遍历顺序相同。

(3)层次遍历:与二叉树的层次遍历思想基本相同,按层次访问结点。

森林的遍历方法:

(1)先序遍历,若森林非空,按如下规则遍历:

       访问森林中第一棵树的根结点

       先序遍历第一棵树中根结点的子树森林

       先序遍历除第一棵树之后剩余的树构成的森林

(2)中序遍历,若森林非空,按如下规则遍历:

       中序遍历第一棵树中根结点的子树森林

       访问森林中第一棵树的根结点

       中序遍历除第一棵树之后剩余的树构成的森林

树和森林的遍历:可采用对应二叉树的遍历算法来实现,如下表

表1-树和森林的遍历和二叉树遍历的关系

森林

二叉树

先根遍历

先序遍历

先序遍历

后根遍历

后序遍历

后序遍历

 

posted @ 2016-05-28 13:39  创心coder  阅读(317)  评论(0编辑  收藏  举报