四、树、森林与二叉树的转化
在讲树的存储结构时,我们提到了树的孩子兄弟法可以将一棵树用二叉链表进行存储,所以借助二叉链表,树和二叉树可以相互进行转换。从物理结构来看,它们的二叉链表也是相同的,只是解释不太一样而已。 因此,只要我们设定一定的规则,用二叉树来表示树,甚至表示森林都是可以的,森林与二叉树也可以互相进行转换。
1.树转换为二叉树
每个结点左指针指向它的第一个孩子,右指针指向它在树中的相邻右兄弟,这个规则又称“左孩子右兄弟”。由于根结点没有兄弟,所以对应的二叉树没有右子树。
树转换成二叉树的画法:
- 在兄弟结点之间加一连线;
- 对每个结点,只保留它与第一个孩子的连线,而与其他孩子的连线全部抹掉;
- 以树根为轴心,顺时针旋转45°。
2.森林转化为二叉树
森林是由若干棵树组成的,所以完全可以理解为,森林中的每一棵树都是兄弟,可以按照兄弟的处理办法来操作。
森林转换成二叉树的画法:
- 将森林中的每棵树转换成相应的二叉树;
- 每棵树的根也可视为兄弟关系,在每棵树的根之间加一根连线;
- 以第一棵树的根为轴心顺时针旋转45°。
至于二叉树转换为树或者二叉树转换为森林只不过是上面步骤的逆过程,在此不做赘述。
五、树、森林的遍历
关系:
树 | 森林 | 二叉树 |
---|---|---|
先根 | 先序(对森林里每一个树的先根) | 先序 |
后根 | 中序(对森林里每一个树的后根) | 中序 |
1.树的遍历
树的遍历是指用某种方式访问树中的每个结点,且仅访问一次。主要有两种方式:
- 先根遍历。若树非空,先访问根结点,再依次遍历根结点的每棵子树,遍历子树时仍遵循先根后子树的规则。其遍历序列与这棵树相应二叉树的先序序列相同。
- 后根遍历。若树非空,先依次遍历根结点的每棵子树,再访问根结点,遍历子树时仍遵循先子树后根的规则。其遍历序列与这棵树相应二叉树的中序序列相同。
下图的树的先根遍历序列为A BEF C DG,后根遍历序列为EFB C GDA。
另外,树也有层次遍历,与二叉树的层次遍历思想基本相同,即按层序依次访问各结点。
树的先根遍历和后根遍历是深度优先遍历。
树的层次遍历是广度优先遍历。
2.森林的遍历
按照森林和树相互递归的定义,可得到森林的两种遍历方法。
- 先序遍历。若森林为非空,则按如下规则进行遍历:
- 访问森林中第一棵树的根结点。
- 先序遍历第一棵树中根结点的子树森林。
- 先序遍历除去第一棵树之后剩余的树构成的森林。
- 中序遍历。森林为非空时,按如下规则进行遍历:
- 后序遍历森林中第一棵树的根结点的子树森林。
- 访问第一棵树的根结点。
- 后序遍历除去第一棵树之后剩余的树构成的森林。
森林的先序遍历序列为ABCD EF GHI,后序遍历序列为BCDA FE HIG。
当森林转换成二叉树时,其第一棵树的子树森林转换成左子树,剩余树的森林转换成右子树,可知森林的先序和后序遍历即为其对应二叉树的先序和中序遍历。