Java面试题三

这是一篇关于Java面试的选择题集锦,涵盖了二叉树遍历、数据结构性能分析、排序算法复杂度、堆排序原理、进程间通信、静态变量存储区域、数据库查询优化、IP地址分类、HTTP状态码含义、进制转换、TCP/IP协议栈、线程共享内容、构造函数执行顺序、递归函数特性、编译过程解析等方面的知识。
摘要由CSDN通过智能技术生成

(此系列试题来源于Java面试宝典书籍)

一、选择题

1.  已知一颗二叉树,如果先序遍历的节点顺序是:ADCEFGHB,中序遍历是:CDFEGHAB,则后序遍历结果为:

  • A. CFHGEBDA
  • B. CDFEGHBA
  • C. FGHCDEBA
  • D. CFHGEDBA

解析:

二叉树

  • 前序遍历:根结点     左子树    右子树
  • 中序遍历:左子树     根节点    右子树  
  • 后序遍历:右子树     根节点    左子树

思路:

  • 根据前序遍历可以知道根节点
  • 通过根节点将中序遍历分为两截进行递归操作
public class BinaryTree {

    static class Node{

        String value;
        Node leftTree;
        Node rightTree;

        public Node(String value, Node leftTree, Node rightTree) {
            this.value = value;
            this.leftTree = leftTree;
            this.rightTree = rightTree;
        }
        void printValue(){
            System.out.println(value);
        }
    }

    public static Node createNode(String value){
        return new Node(value,null,null);
    }

    public static Node createNode(char value){
        return createNode(String.valueOf(value));
    }

    /**
     * 添加节点到左子树
     */
    public static void addNodeToLeft(Node root,Node child){
        if (root.leftTree == null){
            root.leftTree = child;
        }else {
            throw new RuntimeException("the left child has already created");
        }
    }

    /**
     * 添加节点到右子树
     */
    public static void addNodeToRight(Node root, Node child) {
        if (root.rightTree == null) {
            root.rightTree = child;
        } else {
            throw new RuntimeException("the right child has already created");
        }
    }

    /**
     * 前序遍历
     */
    public static void preShow(Node root){
        root.printValue();
        if (root.leftTree != null){
            preShow(root.leftTree);
        }
        if (root.rightTree != null){
            preShow(root.rightTree);
        }
    }

    /**
     * 中序遍历
     */
    public static void midShow(Node root){
        if (root.leftTree != null){
            midShow(root.leftTree);
        }
        root.printValue();
        if (root.rightTree != null){
            midShow(root.rightTree);
        }
    }

    /**
     * 后序遍历
     */
    public static void postShow(Node root){
        if (root.leftTree != null){
            postShow(root.leftTree);
        }
        if (root.rightTree != null){
            postShow(root.rightTree);
        }
        root.printValue();
    }

    /**
     *  根据前序和中序遍历,推断后序遍历
     */
    public static Node createTreeByPreAndMid(Node root,String pre_values,String mid_values){
        if (!"".equals(mid_values)){
            //  同步先序和中序字符串
            String new_pre_values = synchronizedPreAndMid(pre_values,mid_values);
            //这样可以保证,先序的第一个肯定是这棵树的根节点
            char rootValue = new_pre_values.charAt(0);
            root = createNode(rootValue);
            int rootIndexOfIn = mid_values.indexOf(rootValue);//得到根节点在中序中的位置

            // 根节点左边的一大串
            String leftMidValues = mid_values.substring(0,rootIndexOfIn);
            // 根节点右边的一大串
            String rightMidValues = mid_values.substring(rootIndexOfIn+1,mid_values.length());

            // 如果左边一大串就剩下一个了,
            // 说明这肯定就是这课树的左节点,如果还剩下多个就继续递归调用
            if(leftMidValues.length() == 1){
                addNodeToLeft(root, createNode(leftMidValues));
            }else if(leftMidValues.length() != 0){
                addNodeToLeft(root, createTreeByPreAndMid(root, new_pre_values, leftMidValues));
            }

            // 如果右边一大串就剩下一个了,
            // 说明这肯定就是这课树的右节点,如果还剩下多个就继续递归调用
            if(rightMidValues.length() == 1){
                addNodeToRight(root, createNode(rightMidValues));
            }else if(rightMidValues.length() != 0){
                addNodeToRight(root, createTreeByPreAndMid(root, new_pre_values, rightMidValues));
            }

        }
        return root;

    }

    /**
     * 每次都把在pre_values但是不在in_values里面的元素删掉,但是顺序不要变
     */
    private static String synchronizedPreAndMid(String preValues, String midValues) {
        String retVal = "";

        for (int i = 0; i < preValues.length(); i++) {
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值