校招编程题(四) 二叉树之根据前序和中序遍历求按照深度优先遍历打印的序列

摘要

根据前序遍历和中序遍历求该二叉树按层遍历的序列。


import java.util.Arrays;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeMap;

/************************************
 *                                  *
 *  @Modification  优化程序                        *
 *                                  *
 *  @version       1.0.1            *
 *                                  *
 *  @author        何明胜                            *
 *                                  *
 *  @Date   2017-04-02   12:38:04   *
 *                                  *
 ************************************/

public class FormerAndInTraToTree {
    int former_traversal[];//前序遍历数组
    int former_cursor = 0;//前序遍历数组游标
    int in_traversal[];//中序遍历数组

    int []result;//结果存储数组
    TreeMap tree_map = new TreeMap();//结果在树中的下标

    //初始化函数
    public void init(){
        @SuppressWarnings("resource")
        Scanner scanner = new Scanner(System.in);

        int len = scanner.nextInt();//树中元素的个数

        //初始化
        former_traversal = new int[len];
        in_traversal = new int[len];
        result = new int[len];

        //读入前序遍历
        for(int i=0;i//读入中序遍历
        for(int j=0;j//开始执行函数
    public void start() {   
        /*递归调用入口
        //第一个参数为当前根节点的下标,初始化为树的根节点1
        //第二个参数为当前根节点在中序遍历中的位置下标
        //第三个参数为当前中序数组
        //前序遍历顺序:根节点->左子节点->右子节点     中序遍历:左子节点->根节点->右子节点     
        //前序遍历是对根节点的遍历,根据前序遍历游标former_cursor的值遍历前序遍历数组former_traversal的所有根节点
        //确定每个根节点在中序遍历数组中的位置,//赋值给结果数组,下标为当前root//
        //在该数组中其元素左边的元素为其左字树,右边为其右子树
        //对其子树继续递归,//左子树根节点下标为当前root*2,右子树根节点下标为当前root*2+1//
        //直到其左边或者右边只有一个元素时,则为其左子节点和右子节点
        //赋值给结果数组,//左子节点下标为当前root*2,右子节点下标为root*2+1//
        */      
        myRecursive(1,inThisChild(in_traversal), in_traversal);

        //打印最终结果。tree自动排序,跟key中存储的下标值,按序打印结果
        for(Iterator iterator = tree_map.keySet().iterator();iterator.hasNext();){
            int tree_num = tree_map.get(iterator.next());
            System.out.print(result[tree_num]+ " ");
        }
    }

    //递归调用函数
    public void myRecursive(int root, int root_in_tra, int in_tra[]){
        //赋值当前根节点
        tree_map.put(root, former_cursor);//当前节点对应的下标为key,当前节点在数组中的下标为value
        result[former_cursor++] = in_tra[root_in_tra];//当前节点赋值给结果数组
        //中序遍历当前节点已赋值,前序中游标former_cursor加1

        if(1 == root_in_tra){//当前根节点为1,左边只有一个元素,为其左子节点
            tree_map.put(root*2, former_cursor);//保存当前根节点的下标
            result[former_cursor++] = in_tra[0];//赋值给当前根节点左子节点
            //中序遍历当前节点已赋值,前序中游标former_cursor加1
        }
        else if(0 != root_in_tra){//排除当前根节点在数组最左边的情况
            //截取当前根节点左边的元素(左子树)为新数组
            int left_child[] = Arrays.copyOfRange(in_tra, 0, root_in_tra);

            //判断当前根节点是否在左子树中
            if(inThisChild(left_child) > -1){
                myRecursive(root*2, inThisChild(left_child), left_child);
            }
        }

        if(1 == (in_tra.length-1 -root_in_tra)){//当前根节点右边只有一个元素,为其右子节点
            tree_map.put(root*2+1, former_cursor);
            result[former_cursor++] = in_tra[root_in_tra+1];//赋值给右子节点
            //中序遍历当前节点已赋值,前序中游标former_cursor加1
        }
        else if(0 != (in_tra.length-1 -root_in_tra)){//排除当前根节点在数组最右边的情况
            //截取当前根节点右边的元素(右子树)为新数组
            int right_child[] = Arrays.copyOfRange(in_tra, root_in_tra+1, in_tra.length);

            //判断当前根节点是否在右子树中
            if(inThisChild(right_child) > -1){
                myRecursive(root*2+1, inThisChild(right_child), right_child);
            }
        }
    }

    //判断当前游标对应的根节点是否在传入的子树中
    public int inThisChild(int []array){
        for(int i=0;iif(array[i] == former_traversal[former_cursor])
                return i;//若在,返回其在该子树(数组)中的下标
        }
        return -1;//若不在,返回-1
    }

    public static void main(String[] args) {
        FormerAndInTraToTree test = new FormerAndInTraToTree();//实例化
        test.init();//初始化
        test.start();//开始执行
    }
}

你可能感兴趣的:(校招编程题)