vlambda博客
学习文章列表

二叉树的深度优先遍历逆推



二叉树的深度优先遍历有三种方式,分别叫做先序遍历(preorder)、中序遍历(inorder)和后序遍历(postorder),它们之间的不同在于访问每个节点的次序不同。

参考:

一、二叉树的遍历逆推

先序遍历的遍历顺序为:根节点 -> 左子树 -> 右子树。


中序遍历的遍历顺序为:左子树 -> 根节点 -> 右子树。


后序遍历的遍历顺序为:左子树 -> 右子树 -> 根节点。


对于二叉树的三种遍历方式,当知道了其中的任意两种遍历方式,就可以唯一确定一棵树的结构,然后顺利地得到第三种遍历的顺序。


已知先序遍历和中序遍历的遍历顺序,可以先逆推出树的结构,然后得出后序遍历的遍历顺序。同理,已知先序遍历和后序遍历的遍历顺序,可以逆推出中序遍历的遍历顺序,已知中序遍历和后序遍历的遍历顺序,也可以逆推出先序遍历的遍历顺序。


二、二叉树遍历逆推案例


现有一棵二叉树,已知二叉树的先序遍历顺序和中序遍历顺序。


先序遍历的顺序为:A G B E J H C D F I 。


中序遍历的顺序为:B G J E H A D C I F 。


请写出该二叉树的后序遍历顺序。


要得到二叉树的后序遍历,先逆推出二叉树的结构。

1. 先看先序遍历结果,访问的第一个节点一定是根节点,所以可以确定树的根节点是 A。带着这个信息看中序遍历结果,中序遍历是先遍历左子树,根节点在中间,最后遍历右子树,所以从中序遍历的结果中找到 A,A 左边的节点全部都在左子树中,A 右边的节点全部都在右子树中。

根据第一步分析,初步得出二叉树的伪结构如下图。


二叉树的深度优先遍历逆推


2. 现在还差左子树的结构和右子树的结构不明确,先分析左子树,从先序遍历结果和中序遍历结果中将左子树的节点独立出来。


左子树先序遍历的顺序为:G B E J H 。


左子树中序遍历的顺序为:B G J E H 。


在左子树中,先序遍历第一个访问的节点一定是根节点,所以可以确定左子树的根节点是 G。带着这个信息看中序遍历结果,从中序遍历的结果中找到 G,G 左边的节点全部都在 G 的左子树中,G 右边的节点全部都在 G 的右子树中。


分析到这里,可以得出左子树的伪结构如下图。


二叉树的深度优先遍历逆推


3. 用相同的方法分析右子树,从先序遍历结果和中序遍历结果中将右子树的节点独立出来。


右子树先序遍历的顺序为:C D F I 。


右子树中序遍历的顺序为:D C I F 。


在右子树中,先序遍历第一个访问的节点一定是根节点,所以可以确定左子树的根节点是 C。带着这个信息看中序遍历结果,从中序遍历的结果中找到 C,C 左边的节点全部都在 C 的左子树中,C 右边的节点全部都在 C 的右子树中。


于是,可以得出右子树的伪结构如下图。

二叉树的深度优先遍历逆推


4. 将左子树和右子树拼接到根节点上,二叉树的伪结构如下图,又进了一步。

二叉树的深度优先遍历逆推


5. 现在还差节点 G 的右子树和节点 C 的右子树结构不明确,快速用相同的方法分析,结构分别为下图中的图左和图右。

二叉树的深度优先遍历逆推


6. 将子树拼接回二叉树中,得出了二叉树的完整结构如下图。

二叉树的深度优先遍历逆推


7. 逆推出了树的结构,可以快速得出二叉树后序遍历的顺序了。


后序遍历的顺序为:B J H E G D I F C A 。


总结上面的过程,都是先在先序遍历中找到根节点,然后在中序遍历中切分左子树和右子树,再递归。如果已知中序遍历和后序遍历的顺序,也可以先在后序遍历中找到根节点,然后在中序遍历中切分左子树和右子树,再递归即可。


三、二叉树遍历逆推案例二


如果已知的是先序遍历和后序遍历的顺序,先序遍历和后序遍历都可以轻易找到根节点,但是没有中序遍历来切分左右子树,怎么逆推出中序遍历呢?


直接看案例吧,已知二叉树的先序遍历顺序和后序遍历顺序。


先序遍历的顺序为:10 70 60 20 40 90 50 80 30 。


后序遍历的顺序为:60 40 90 20 70 80 30 50 10 。


请写出该二叉树的中序遍历顺序。

1. 先看先序遍历结果,访问的第一个节点一定是根节点,所以可以确定树的根节点是 10。先序遍历访问完根节点后,会先访问左子树再访问右子树,左子树的节点一定都排在右子树的前面,并且访问左子树也是先访问根节点,所以访问的第二个节点一定是左子树的根节点,左子树的根节点是 70。


带着这个信息看后序遍历结果,后序遍历的根节点一定排在其他节点的最后,左子树也一样,左子树的根节点也一定排在左子树其他节点的最后。左子树的根节点是 70,所以 70 及左边的节点全部都在左子树中,除了根节点,70 右边的节点全部都在右子树中。


这样,就分析出了树的根节点是 10,左子树中的节点为 60 40 90 20 70,右子树中的节点为 80 30 50。


2. 现在将左子树独立出来分析,在后序遍历中已经找到了左子树的全部节点,共5个节点,直接将这个5个节点独立出来即可。到先序遍历中,去掉根节点,按顺序取5个节点,就是左子树的先序遍历。


左子树先序遍历的顺序为:70 60 20 40 90 。


左子树后序遍历的顺序为:60 40 90 20 70 。


用同样的方法进行分析,可知 70 的左子树只有 60 一个节点,70 的右子树有 40 90 20 三个节点。


3. 继续用同样的方法对右子树分析,如果左子树和右子树中还有子树,继续使用相同的方法递归逆推。


4. 最终得出树的结构如下图。


5. 逆推出了树的结构,可以快速得出二叉树中序遍历的顺序了。


中序遍历的顺序为:60 70 40 20 90 10 80 50 30 。


以上就是二叉树的深度优先遍历逆推了。