zoukankan      html  css  js  c++  java
  • 重建二叉树

    问题

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

    思路

      首先找到先序遍历的第一个节点,就是根节点,然后在中序遍历中找到根节点。此时,根节点左右两边,分别是左右子树的中序遍历。再对于先序遍历,从第二个节点开始,到中序遍历中左子树的长度,就是左子树的先序遍历。同理,右子树也是一样,这是一个递归过程。

        public BinaryTreeNode getTheRoot(List<Integer> preorder,
                List<Integer> inorder, int count) {
    
            //前序排列中的第一个数字为当前根节点的值
            int rootValue = preorder.get(0);
            BinaryTreeNode root = new BinaryTreeNode();
            root.value = rootValue;
    
            //如果count=1,则表示当前节点为叶子节点,直接返回
            if (count == 1) {
    
                return root;
            }
    
            // 根节点的值在中序排列中的位置
            int index = 0;
            for (int i : inorder) {
    
                if (i == rootValue) {
    
                    break;
                }
                index++;
            }
    
            //表示在中序排列中没有找到根节点的值,则表示前序排列或者中序排列的输入有误
            if (index == count) {
    
                throw new RuntimeException("错误的排序输入!");
            }
    
            //如果index > 0,则表示当前有左子树
            if (index > 0) {
    
                // 左子树的前序排列从当前前序排列的第二个值(去掉当前根节点)开始,包含左子树个数个值(index)
                List<Integer> startPreorder = preorder.subList(1, (index + 1));
                // 左子树的中排列从当前中序排列的第一个值开始,直到根节点的位置(不包含根节点)
                List<Integer> startInorder = inorder.subList(0, index);
                
                root.left = getTheRoot(startPreorder, startInorder, index);
            }
    
            //如果index > 0,则表示当前有有子树
            if (index < count - 1) {
                
                List<Integer> endPreorder = preorder.subList((index + 1), count);
                List<Integer> endInorder = inorder.subList((index + 1), count);
                
                //这里为什么是count - index - 1 大家可以画图思考一下
                root.right = getTheRoot(endPreorder, endInorder, (count - index - 1));
            }
            
            return root;
        }

    总结

      首先要熟悉二叉树的前序遍历,中序遍历,以及后序遍历,再加上递归的思想,就可以实现。

  • 相关阅读:
    区块链|学习笔记(三)
    左神算法之获取栈中最小值
    23种设计模式之适配器模式
    二叉树序列化和反序列化
    归并排序
    通过集合构建RDD或者DataFrame
    内核源码分析——shuffle
    问题
    函数参数
    问题记录
  • 原文地址:https://www.cnblogs.com/a294098789/p/5400557.html
Copyright © 2011-2022 走看看