二叉树遍历

题目描述:

    给定一棵二叉树的前序遍历和中序遍历,求其后序遍历。(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)

输入:

    两个字符串,其长度n均小于等于26

    第一行为前序遍历,第二行为中序遍历。二叉树中的结点名称以大写字母表示:A,B,C,D...

最多26个结点

输出:

    输出样例可能有多组,对于每组测试样例,输出一行,为后序遍历的字符串。

样例输入

    ABC
    BAC
    FDXEAG
    XDEFAG

样例输出:

    BCA
    XEDGAF

 

解题思路:

   二叉树的还原(buildTree方法): 利用递归的思想。

  1.  由(最初得到的)前序排列和中序排列的字符串,得到根节点;
  2. 根据跟结点的索引,将前序排列和中序排列的字符串划分为:左子树的前序、中序排列;右子树的前序、中序排列;
  3. 对于每对前序中序排列,重复步骤1,2;
  4. 最终得到完整的二叉树。

 

示例代码:

import java.util.Scanner;

public class Main {
    public static Node buildTree(String preorder,String midorder, int s1,int e1,int s2,int e2){
        //取出待处理的序列的根结点"权重"
        char c = preorder.charAt(s1);
        //创建根结点对象
        Node root = new Node(c,null,null);
        //找出中序排列得到的序列中,根结点的索引
        //为之后将preorder和midorder分为左右子树两部分做准备
        int rootIndex = 0;
        for (int i=s2;i<e2;i++){
            if (midorder.charAt(i)==c){
                rootIndex=i;
                break;
            }
        }

        //重点!!!
        /*对序列进行拆分,分为左子树序列和右子树序列,分裂依据为当前根结点*/
        String left_preorder = preorder.substring(1,rootIndex+1);
        //对preorder长度做出判断,若preorder为空,则不需要进行子树的生成
        if (left_preorder.length()!=0){
            String left_midorder = midorder.substring(0,rootIndex);
            root.lchild = buildTree(left_preorder,left_midorder,0,left_preorder.length(),0,left_midorder.length());
        }
        String right_preorder = "";
        //对索引下标进行比较,防止当rootIndex+>e1时,产生字符串索引超出边界异常
        if (rootIndex+1<e1){right_preorder =preorder.substring(rootIndex+1,e1); }
        if (right_preorder.length()!=0){
            String right_midorder = "";
            if (rootIndex+1<e2){right_midorder = midorder.substring(rootIndex+1,e2);}
            root.rchild = buildTree(right_preorder,right_midorder,0,right_preorder.length(),0,right_midorder.length());
        }
        return root;//返回生成的binaryTree
    }
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            //前序遍历得到的序列
            String preorder = scanner.next();
            String midorder = scanner.next();
            int s1=0;
            int s2=0;
            int e1= preorder.length();
            int e2= midorder.length();
            Node root = buildTree(preorder,midorder,s1,e1,s2,e2);
            String post_string = root.postorder(root);
            System.out.println(post_string);
        }
    }
}


public class Node {
    //每一个结点包含自身标记,其左子树结点,右子树结点
    public char c;
    public Node lchild;
    public Node rchild;

    public Node(char c,Node lchild,Node rchild){
        this.c = c;
        this.lchild = lchild;
        this.rchild = rchild;
    }

    String pre_str = "";
    String mid_str = "";
    String post_str = "";

    //前序遍历
    public String preorder(Node root){
        pre_str += root.c;
        if (root.lchild!=null){preorder(root.lchild);}
        if (root.rchild!=null){preorder(root.rchild);}
        return pre_str;
    }

    //中序遍历
    public String midorder(Node root){
        if (root.lchild!=null){midorder(root.lchild);}
        mid_str += root.c;
        if (root.rchild!=null){midorder(root.rchild);}
        return mid_str;
    }

    //后序遍历
    public String postorder(Node root){
        if (root.lchild!=null){postorder(root.lchild);}
        if (root.rchild!=null){postorder(root.rchild); }
        post_str += root.c;
        return post_str;
    }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值