细解 二叉树:已知先序和中序求后序,已知中序和后序求先序

树的三种遍历方式的遍历顺序:

先序遍历:根、左子树、右子树(特点:第一个元素为根)
中序遍历:左子树、根、右子树(特点:根的两边分别为左子树和右子树)
后序遍历:左子树、右子树、根(特点:最后一个元素为根)
有如下图的二叉树:
其先序、中序、后序遍历分别为:DBACEGF、ABCDEFG、ACBFGED。
1、已知先序和中序求后序
先序遍历的第一个字符为根,因此只需在中序遍历中找到它,就可以把根节点的左子树和右子树分开,就可以知道左子树的字符个数和右子树的字符个数,然后可以确定先序遍历中哪部分是左子树,哪部分是右子树,之后递归先序遍历的序列,直到结束。
如上面的例子:先序遍历的第一个字符是D,则根节点为D,从中序遍历中可以找到D的位置,左边的ABC即为左子树的字符,右边的EFG即为右子树的字符,如果开始递归函数为:build(“DBACEGF”),则找到根的位置后,可以分为递归左子树的先序遍历和递归右子树的先序遍历:build(“BAC”)和build(“EFG”),其对应的中序遍历为:ABC和EFG。然后继续进行以上步骤,直到找完先序序列。每找到根就可以直接输出或保存到数组中,需要注意的是递归的时候不要把根包含在内。
代码如下(已知先序和中序求后序):
 

//前 中序构造树
public static Node tree(int[] zx, int[] hx, int l1,int r1, int l2,int r2) {
    if (l1>r1) return null;
    int i;
    Node root = new Node();
    for (i = l1;!(zx[i]==hx[l2]); i++);     //找到根节点
    root.data=hx[l2];
    int cnt = i-l1;    //求出左子树个数
    root.L=tree(zx,hx,  l1,  i-1,        l2+1,  l2+cnt);   //左子树
    root.R=tree(zx,hx,  i+1,  r1,        l2+cnt+1,  r2);   //右子树
    return root;
}
 //中后序
root.L=tree(zx,hx,  l1,  i-1,        l2,  l2+cnt-1);   //左子树
 root.R=tree(zx,hx,  i+1,  r1,        l2+cnt,  r2-1);   //右子树

图解

大家看到没,其实两个代码差不多,前面都是一样的,因为后序的根在后面,前序的根在前面,前面后面的不同

猜你喜欢

转载自blog.csdn.net/qq_40674583/article/details/86253048