第一次总结,个人浅见,望大牛们轻削,怕疼,呵呵~~~
1.已知前序遍历和中序遍历序列,可以唯一确定一棵二叉树。
2.已知后序遍历和中序遍历序列,可以唯一确定一棵二叉树。
3.已知后续遍历和前序遍历序列,不能唯一确定一棵二叉树。
综上:要想唯一确定一个二叉树,必须要有中序遍历序列。
遍历规则:
1、先序或者前序遍历规则:根左右
2、中序遍历规则:左根右
3、后序遍历规则:左右根
例子1:前序:abcdef,中序:cbaedf,后序=?
根据前序规则:根左右,根是第一个被遍历的,那么这棵树的根就是a,那么就可以将中序遍历分隔出来左子树和右子树了
左子树:b、c 右子树:d、e、f
如下:
前序 a|bc|def
中序 cb|a|edf
左子树:
左子树前序遍历顺序为bc,首先遍历左子树的"根",则b为左子树的根节点
中序遍历顺序为cb,遍历顺序为左根右,则可知c为b的左叶子节点
右子树:
前序遍历规则:根左右,右子树的"根"为d,则e、f是d的子节点
中序遍历规则:左根右,e是d的左叶子节点,f是d的右叶子节点
此时就把这棵树的左子树和右子树确定了下来,如下:
a
/ \
b d
/ / \
c e f
再根据后序遍历规则:左右根,可知后序遍历结果:cbefda
详解:先从左子树遍历,先找到左叶子节点c,然后左右根规则,b节点没有右叶子节点,遍历"根",则此时为cb,左子树遍历完毕,根据左右根规则,整棵树的根是最后遍历的,先遍历完左子树,然后遍历右子树,最后遍历整棵树的根遍历右子树,根据左右根规则,找到左叶子节点e,然后遍历f,再遍历d,则此时右子树遍历为efd,右子树遍历完毕,最后遍历整棵树的根a。完整的后序遍历顺序就是:cbefda
小结:
(1)根据前(先)序判断根节点,从中序分隔左子树和右子树
(2)然后根据先序,中序遍历规则结合,分别处理左右子树,将树的节点顺序确定下来
(3)最终确定整棵树,画出来,最后再根据后序遍历规则进行遍历即可。
例子2:中序:abcdefg,后序:bdcafge,前(先)序=?
根据后序遍历规则:左右根,可知,根是最后遍历的节点,那么e就是整棵树的根节点。然后根据中序遍历规则:左根右,e又是根节点,那么必定有左子树(如果没有左子树a就是根节点),可知a一定在左子树中,那么可以将中序和后序结果分出左子树和右子树来
左子树:a、b、c、d 右子树:e、f、g
如下:
中序:abcd|efg
后序:bdca|fge
右子树:
右子树节点少,先处理右子树,已知e为树的根节点,
中序遍历规则为:左根右,有以下情况:
(1)f若是右子树的左叶子节点,g则是右子树根节点;
(2)f若是右子树的根节点,g则是右子树的右叶子节点
后序遍历规则:左右根,根据中序遍历情况(1),f右子树的左叶子节点,g右子树根节点的规则,可以得出fg的遍历结果;
根据中序遍历情况(2),那么首先遍历的节点应该是g,之后是f,和正确结果不符,那么第一种情况就是我们想要的结果。
此时右子树节点顺序确定完毕,结果为:f是右子树的左叶子节点,g是右子树根节点
左子树:
看左子树后序遍历结果:bdca,根据左右根规则可知,a是左子树的根节点,那么就是确定b、c、d在左子树中的顺序了
看左子树中序遍历结果abcd,a是左子树根节点,并且a节点没有左子节点(如果有,那么中序遍历就从a的左子节点开始,不符合题目中的中序遍历结果),所以bcd组成了a节点的右子树,此处定义a节点的右子树为A子树。
情况如下:
(1)b为A子树的左叶子节点,则c为A子树根节点,d为A子树的右叶子节点
(2)b为A子树的根节点,则c为A子树的右子节点,d为c的右叶子节点
有点绕啊,不好意思~~~~这时候其实就应该在纸上画出图形了,直观和容易比对出现的情况
后序遍历结果:bdc(a已知为左子树根节点,暂不考虑)
规则:左右根
根据中序遍历情况(1),b为左叶子节点,d为右叶子节点,c为"根"节点,可以得出bdc的结果
根据中序遍历情况(2),后序遍历结果为:dcb, 和题目中正确后序遍历结果不一致,那么第一种情况就是我们要的结果,此时左子树可以确定节点顺序,结果:定义a节点的右子树为A子树。b为A子树的左叶子节点,c为A子树根节点,d为A子树的右叶子节点
此时就把这棵树的左子树和右子树确定了下来,如下:
e
/ \
a g
\ /
c f
/ \
b d
再根据先序遍历顺序:根左右,可知先序遍历顺序:eacbdgf
详解:先从整棵树的根开始遍历,e,然后遍历左子树,左子树根为a,左子树没有左子节点,开始遍历右子节点,"根"为c,遍历左子节点b,右子节点d,此时左子树遍历完毕,结果为eacbd遍历右子树,右子树根节点为g,然后遍历左子节点为f,此时右子树遍历完毕,结果:gf
整棵树先序遍历完毕,结果:eacbdgf
小结:
(1)根据后序遍历结果找出整棵树的根节点
(2)根据中序遍历的起始节点将后序遍历和中序遍历结果分隔成左子树和右子树
(3)先处理节点较少的子树,再处理节点较多的子树
(4)根据后序遍历结果区分出来的子树序列节点的最后一个节点,确定为该子树的根节点
(5)然后对剩下的节点根据中序遍历顺序假设各种情况,用后序遍历规则对这些情况进行套用,找出符合后序遍历结果的那种情况。
如果分隔出来的左右子树节点多而复杂可以继续套用(4)、(5),进行区分处理
以上是小弟的个人浅见,可能大家还有更多更好更简便的方法,希望大家能够互相交流讨论。