zoukankan      html  css  js  c++  java
  • 【面试】重建二叉树

    一、描述

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

    class BinaryTreeNode {
        int m_nValue;
        BinaryTreeNode m_pLeft;
        BinaryTreeNode m_pRight;
    
        public BinaryTreeNode(int m_nValue, BinaryTreeNode m_pLeft, BinaryTreeNode m_pRight) {
            this.m_nValue = m_nValue;
            this.m_pLeft = m_pLeft;
            this.m_pRight = m_pRight;
        }
    }

    二、解题思路

      可以根据前序遍历序列结合中序遍历序列找到某个结点的左子树和右子树,从而使用递归完成求解。

    三、代码

    package com.hust.grid.leesf.chapter2;
    
    import java.util.Scanner;
    
    class BinaryTreeNode {
        int m_nValue;
        BinaryTreeNode m_pLeft;
        BinaryTreeNode m_pRight;
    
        public BinaryTreeNode(int m_nValue, BinaryTreeNode m_pLeft, BinaryTreeNode m_pRight) {
            this.m_nValue = m_nValue;
            this.m_pLeft = m_pLeft;
            this.m_pRight = m_pRight;
        }
    }
    
    public class ConstructBinaryTree {
        public static BinaryTreeNode construct(int[] preOrder, int[] inOrder, int length) throws Exception {
            if (preOrder == null || inOrder == null || length <= 0) {
                return null;
            }
            return constructCore(preOrder, 0, preOrder.length - 1, inOrder, 0, inOrder.length - 1);
        }
    
        public static BinaryTreeNode constructCore(int[] preOrder, int startPreIndex, int endPreIndex,
                                                   int[] inOrder, int startInIndex, int endInIndex) throws Exception {
            int rootValue = preOrder[startPreIndex];
            BinaryTreeNode root = new BinaryTreeNode(rootValue, null, null);
            // 只有一个元素,为递归的出口
            if (startPreIndex == endPreIndex) {
                if (startInIndex == endInIndex
                        && preOrder[startPreIndex] == inOrder[startInIndex]) {
                    return root;
                } else {
                    throw new Exception("invalid input");
                }
            }
            // 在中序遍历中找到根结点
            int rootInIndex = startInIndex;
            while (rootInIndex <= endInIndex && inOrder[rootInIndex] != rootValue) {
                ++rootInIndex;
            }
            if (rootInIndex == endInIndex && inOrder[rootInIndex] != rootValue) {
                throw new Exception("invalid input");
            }
            int leftLength = rootInIndex - startInIndex;
            int leftPreOrderEndIndex = startPreIndex + leftLength;
            if (leftLength > 0) {
                // 构建左子树
                root.m_pLeft = constructCore(preOrder, startPreIndex + 1,
                        leftPreOrderEndIndex, inOrder, startInIndex,
                        rootInIndex - 1);
            }
            if (leftLength < endPreIndex - startPreIndex) {
                // 右子树存在元素,构建右子树
                root.m_pRight = constructCore(preOrder, leftPreOrderEndIndex + 1,
                        endPreIndex, inOrder, rootInIndex + 1, endInIndex);
            }
            return root;
        }
    
        public static void main(String[] args) throws Exception {
            Scanner scan = new Scanner(System.in);
            String preOrderInput = scan.nextLine();
            String inOrderInput = scan.nextLine();
            int[] preOrder = new int[preOrderInput.length()];
            int[] inOrder = new int[inOrderInput.length()];
            for (int index = 0; index < preOrderInput.length(); index++) {
                preOrder[index] =  Integer.parseInt(String.valueOf(preOrderInput.charAt(index)));
            }
            for (int index = 0; index < inOrderInput.length(); index++) {
                inOrder[index] = Integer.parseInt(String.valueOf(inOrderInput.charAt(index)));
            }
            BinaryTreeNode root = construct(preOrder, inOrder, preOrder.length);
            preOrderTraverse(root);
            System.out.println();
            inOrderTraverse(root);
            System.out.println();
            postOrderTraverse(root);
        }
    
        public static void preOrderTraverse(BinaryTreeNode root) {
            if (root != null) {
                System.out.print(root.m_nValue + " ");
                preOrderTraverse(root.m_pLeft);
                preOrderTraverse(root.m_pRight);
            }
        }
    
        public static void inOrderTraverse(BinaryTreeNode root) {
            if (root != null) {
                inOrderTraverse(root.m_pLeft);
                System.out.print(root.m_nValue + " ");
                inOrderTraverse(root.m_pRight);
            }
        }
    
        public static void postOrderTraverse(BinaryTreeNode root) {
            if (root != null) {
                postOrderTraverse(root.m_pLeft);
                postOrderTraverse(root.m_pRight);
                System.out.print(root.m_nValue + " ");
            }
        }
    }
    View Code

    输入结果:

    12473568
    47215386

    输出结果:

    1 2 4 7 3 5 6 8 
    4 7 2 1 5 3 8 6 
    7 4 2 5 8 6 3 1 
  • 相关阅读:
    快使用阿里云的maven仓库
    谈谈对MVC、MVP和MVVM的理解
    [个人项目] 使用 Vuejs 完成的音乐播放器
    手把手教你封装 Vue 组件并使用 NPM 发布
    Chrome 的 Material Design Refresh UI初探
    Vue图片懒加载插件
    手淘的移动端适配方案flexible
    css 实现元素长宽等比缩放
    css 中 stick footer 布局实现
    页面滚动插件 better-scroll 的用法
  • 原文地址:https://www.cnblogs.com/leesf456/p/5815873.html
Copyright © 2011-2022 走看看