• 重建二叉树-牛客网-剑指offer


    1.问题描述

      输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

    2.问题分析

      2.1首先了解二叉树的结构

         2.2了解二叉树的三种遍历顺序(前序遍历,中序遍历和后序遍历)

        前序遍历:中左右

               中序遍历

               后序遍历

      根据前序遍历序列和中序遍历序列,或后序遍历序列和中序遍历序列,能唯一确定二叉树。

      2.3迭代的编程思想

    3.源代码

    package www.nowcoder.com.conquerOffer.binaryTree;
    
    import java.util.Arrays;
    
    /**
     * 重建二叉树
     * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 
     * http://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
     * @author sunny
     *
     */
    public class BinaryTreeRebuild {
        /**
         * 重建二叉树 
         * @param pre 前序遍历序列数组
         * @param in 中序遍历序列数组
         * @return 二叉树根节点
         */
        public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
            //第一步:校验前序遍历序列或中序遍历序列数组是否为空
            if(null == pre || null == in || pre.length <= 0 || in.length <= 0)
                return null;
            //第二步:从前序遍历序列中获取根节点的值
            int rootVal = pre[0];    
            //第三步:设置根节点的值
            TreeNode rootNode = new TreeNode(rootVal);
            //第四步:获取根节点在中序遍历序列中的索引值
            int rootIndex = findInArray(in, rootVal);    //数组工具类自带的二分查找算法
            //第五步:获取左子树的前序遍历序列、右子树的前序遍历序列,左子树的中序遍历序列、右子树的中序遍历序列
            //左子树的前序遍历序列
            int[] preLeft = Arrays.copyOfRange(pre, 1, rootIndex+1);
            //右子树的前序遍历序列
            int[] preRight = Arrays.copyOfRange(pre, rootIndex+1, pre.length);
            //左子树的中序遍历序列
            int[] inLeft = Arrays.copyOfRange(in, 0, rootIndex);
            //右子树的中序遍历序列
            int[] inRight = Arrays.copyOfRange(in, rootIndex+1, pre.length);
            BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild();
            //第六步:构建左子树和右子树
            TreeNode leftTree = binaryTreeRebuild.reConstructBinaryTree(preLeft, inLeft);
            TreeNode rightTree = binaryTreeRebuild.reConstructBinaryTree(preRight, inRight);
            //第七步:设置根节点的左子树和右子树
            rootNode.setLeft(leftTree);
            rootNode.setRight(rightTree);
            return rootNode;
        }
        
        /**
         * 获取数组中目标的下标
         * @param arr 数组
         * @param target 查找的目标 
         * @return
         */
        private static int findInArray(int[] arr, int target) {
            //数组为空
            if(null == arr || arr.length <= 0)
                return -1;
            for(int i = 0; i < arr.length; i++){
                if(target == arr[i])
                    return i;
            }
            return -1;
        }
    
        public static void main(String[] args) {
            //前序遍历序列
            int[] pre = new int[]{1,2,4,7,3,5,6,8};
            //中序遍历序列
            int[] in = new int[]{4,7,2,1,5,3,8,6};
            BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild();
            TreeNode rootNode = binaryTreeRebuild.reConstructBinaryTree(pre, in);
            System.out.println(rootNode);
        }
    
    }
    
    /**
     * 二叉树节点
     * @author sunny
     *
     */
    class TreeNode {
        int val;    //节点值
        TreeNode left;    //左子树
        TreeNode right;    //右子树
        TreeNode(int x) { val = x; }    //构造函数
        //左子树的set方法
        public void setLeft(TreeNode left) {
            this.left = left;
        }
        //右子树的set方法
        public void setRight(TreeNode right) {
            this.right = right;
        }
    }

    4.运行效果

    1 www.nowcoder.com.conquerOffer.binaryTree.TreeNode@28d76d1e
    运行效果
  • 相关阅读:
    Python网络协议(osi七层协议)
    Python面向对象之反射,双下方法
    Python类的成员
    Python异常处理
    mysql 索引 慢查询优化 && 数据库性能优化
    数据库(视图、事务、存储过程、函数) && 数据库备份
    mysql数据库连接模块 pymysql && sql注入
    主线程与子线程的关系
    socket 编程实例 基于线程池实现服务端并发
    日常迷惑积累
  • 原文地址:https://www.cnblogs.com/sunny08/p/4894085.html
Copyright © 2020-2023  润新知