POJ2255

来源:互联网 发布:免费的crm软件 编辑:程序博客网 时间:2024/06/05 11:01

第一种思路采用了类似栈的思路(先拆分出来的反倒后输出)  从根-》树结点 压入栈中,最后出栈,上代码

第二种思路采用了重建二叉树的思想,根据前序+中序可以确定一颗唯一的二叉树,这样就可以前序输出和中序输出序列重建一颗二叉树,在通过重写postOrder方法,来后序输出

/*小情人非常喜欢玩二叉树。
她最喜欢的游戏是在节点上用大写字母构造随机查找的二叉树。
这是她创作的一个例子:
为了给后代记录她的树,她为每棵树写下了两个字符串:
一个前序遍历(根,左子树,右子树)和一个遍历(左子树,根,右子树)。
对于上面绘制的树,前序遍历是DBACEGF,中序遍历是ABCDEFG。
现在,多年以后,
 她再次看到琴弦,意识到重建树木确实是可能的,但仅仅是因为她从来没有在同一棵树上使用同样的两个字母。
然而,手工重建,很快就变得乏味了。
所以现在她要求你写一个能为她做好工作的程序!
输入将包含一个或多个测试用例。
每个测试用例由一行包含两个字符串preord和inord组成,表示二叉树的前序遍历和中序遍历。
两个字符串都由唯一的大写字母组成(因此它们不超过26个字符)
输入由文件结尾终止。
对于每个测试用例,恢复情人节的二叉树并打印包含树的后序遍历(左子树,右子树,根)的一行。
*/
import java.util.*;
public class POJ2255 {
    
    public static void main(String args[]){
        
        Scanner input = new Scanner(System.in);


        while(input.hasNext()){
            
           String pre=input.next();
           String in=input.next();
           String s= getPostOrder(pre, in);
            
           System.out.println(s);
            
        }  
    }
    
    public static String getPostOrder(String pre,String in){
        
        
        if(pre.length()==1&&in.length()==1)
            return in;//递归截止条件
        
        
        char head = pre.charAt(0);
        int n = in.indexOf(head);
        
        if(n==0){//无左子树
            String in2= in.substring(1,in.length());
            String pre2 = pre.substring(1, pre.length());
            return getPostOrder(pre2, in2)+head;
        }


        else if(n==(in.length()-1)){//无右子树
            String in1 = in.substring(0, n);
            String pre1 = pre.substring(1, pre.length());
            return getPostOrder(pre1, in1)+head;
        }
        else {//左右子树都有
        String in1 = in.substring(0, n);
        String in2= in.substring(n+1, in.length());
        
        String pre1 = pre.substring(1, in1.length()+1);
        String pre2 = pre.substring(in1.length()+1, pre.length());
        
        pre = getPostOrder(pre1, in1);
        in = getPostOrder(pre2, in2);
        
        String s = pre+in+head;
       
        return s;
        }
        
    }


}


(2)思路二

import java.util.*;


public class test {

public static void main(String[] args) {

Scanner input = new Scanner(System.in);
while(input.hasNext()) {
String preString  = input.next();
String inString = input.next();

char[] pre = preString.toCharArray();
char[] in = inString.toCharArray();
TreeNode root = reConstructBinaryTree1(pre, in);
postOrder(root);
System.out.println();
}
}


static class TreeNode<E> {
E val;
TreeNode left;
TreeNode right;


TreeNode(E x) {
val = x;
}
}
// 重新构建二叉树
public static TreeNode reConstructBinaryTree1(char[] pre, char[] in) {
// pre先序遍历,in中序遍历
if (pre.length == 0 || in.length == 0 || pre.length != in.length) {
return null;
} // 如果没有遍历,或者遍历不一致,则返回为null
TreeNode root = new TreeNode(pre[0]);// 定义二叉树的根节点
int i = String.valueOf(in).indexOf(pre[0]);
// 找到根节点在中序遍历里的位置,
// 中序遍历中,根节点左侧为左子树节点,右侧为右子树节点
char[] preLeft = new char[i];// 左子树先序遍历
char[] inLeft = new char[i]; // 左子树中序遍历
char[] preRight = new char[pre.length - i - 1];// 右子树先序遍历
char[] inRight = new char[in.length - i - 1];// 右子树中序遍历
for (int j = 0; j < in.length; j++) {
if (j < i) {
preLeft[j] = pre[j + 1];
inLeft[j] = in[j];
} else if (j > i) {
preRight[j - i - 1] = pre[j];
inRight[j - i - 1] = in[j];
}
}
root.left = reConstructBinaryTree1(preLeft, inLeft);// 递归构建左子树
root.right = reConstructBinaryTree1(preRight, inRight);// 递归构建右子树
return root;// 返回重新构建二叉树
}


public static void postOrder(TreeNode tr) {// 后序遍历遍历二叉树
if (tr == null) {
return;
}
postOrder(tr.left);
postOrder(tr.right);
System.out.print(tr.val);
}
}