一:简介
二叉树的遍历分为前序遍历,中序遍历,后续遍历。而如果已经知道了二叉树的遍历情况,怎样快速用人脑推导出二叉树的形状呢。本人以不同的遍历情况给出我的看法。
二:说明
本文以3种情况: (1)已知前序遍历和中序遍历
(2)已知中序遍历和后续遍历
(3)已知前序遍历和后续遍历(这种情况是无法推导出来的,本文将给出解释)
三:原理
首先,先简单谈谈遍历树的原理。
void traverse(Node *T){
if(T){
//如果是前序do something
traverse(T->lchild);
//如果是中序do something
traverse(T->rchild);
//如果是后序do something
}
}
traverse(T->lchild)是对左子树处理,traverse(T->rchild)是对右子树处理。这里,一定要理解为左子树和右子树,而不是结点的左儿子和右儿子。知道了这个,就可以开始正文了。
前序遍历产生的结果如下图:
中序遍历产生的结果如下图:
后序遍历产生的结果如下图:
是不是很有规律性?(如果没懂可以先看后面的例子)。现在开始分情况介绍
(1)前序遍历和中序遍历
在仔细看看前序遍历和后序遍历的结果,会发现,我们可以使用前序遍历的根结点,在中序遍历里,找到左子树和右子树(没错,这就是原理)。然后反复使用这个原理,就能很快推导出树的形状。
废话不多说,看个例子。
先已知前序遍历:ABCDEF,后序遍历:CBAEDF
首先:我们能很快得到左子树,右子树,根。
然后我们可以画出树的大概形状
然后,我们以左子树为目标,再运用一次原理:
这次,再画出树的图
再一次,对右子树:
这次,我们能完完全全的画出树的形状了
(2)中序遍历和后序遍历
现在再仔细看看中序遍历和后序遍历:
我们可以使用后序遍历已知的根来推断左子树和右子树。和上面的方法一样,再依次分析左子树和右子树。就能完成树的推导,这里就不赘述了。
(3)前序遍历和后序遍历
现在再仔细看看前序遍历和后序遍历:
你会发现,我们无法用根来区分左子树和右子树。就举个小栗子:
前序遍历:ABC
后序遍历:CBA
树的形状可以是:
四:结尾
(1)要理解遍历的思想:不断的把树分为左子树和有子树
(2)要理解遍历产生的三种结果,也就是最开始的三张图。
如果通过我的文章理解了树的推导,就给个赞,如果还有疑问,可以发邮件和我讨论 peanwang @outlook.com,或者2387783901@qq.com