【面试】重建二叉树

一、描述

  输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树,假设输入的前序遍历和中序遍历的结果中都不含重复的数字,例如输入前序遍历序列{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 

 

posted @   leesf  阅读(420)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

喜欢请打赏

扫描二维码打赏

了解更多

点击右上角即可分享
微信分享提示