zoukankan      html  css  js  c++  java
  • 剑指Offer之重建二叉树

    题目描述

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

    分析:

    在二叉树的前序遍历中,第一个数字总是树的根节点的值。但在中序遍历序列中,根节点的值在序列的中间,左子树的值位于根节点的左边,而右子树的节点的值位于根节点的值得右边。因此我们需要扫描中序遍历,才能找到根节点的值。

    如下图所示,前序遍历序列的第一个数字1就是根节点的值。扫描中序遍历序列,就能确定根节点的值得位置。根据中序遍历特点,在根节点的值1前面的3个数字都是左子树节点的值,位于1后面的数字都是右子树节点的值。

     由于在中序遍历中,有3个数字是左子树节点的值,因此左子树总共有3个左子节点。同样,在前序遍历中,根节点后面的3个数字就是3个左子树节点的值,再后面的所有数字都是右节点的值。这样我们就在前序遍历和中序遍历两个序列中,分别找到了左右子树对应的子序列。

    Java代码

     1 import java.util.LinkedList;
     2 import java.util.Queue;
     3 import java.util.Scanner;
     4 
     5 /**
     6  * Created by Feng on 2017/5/1.
     7  * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
     8  * 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
     9  */
    10 public class ReConstructBinaryTree {
    11     public static void main(String[] args) {
    12         Scanner sc = new Scanner(System.in);
    13         while (sc.hasNext()) {
    14             int n = sc.nextInt();//二叉树的节点数
    15 
    16             int[] preorder = new int[n];//二叉树先序遍历
    17             for (int i = 0; i < n; i++) {
    18                 preorder[i] = sc.nextInt();
    19             }
    20 
    21             int[] inorder = new int[n];//二叉树中序遍历
    22             for (int i = 0; i < n; i++) {
    23                 inorder[i] = sc.nextInt();
    24             }
    25 
    26             TreeNode root = reConstruct(preorder, inorder);
    27             System.out.print(root.val + " ");
    28 
    29             //使用对列输出重构的二叉树
    30             Queue<TreeNode> queue = new LinkedList<>();
    31             queue.add(root);
    32 
    33             //利用对列先进先出的特点
    34             while (!queue.isEmpty()) {
    35                 TreeNode node = queue.poll();
    36                 if (node.left != null) {
    37                     System.out.print(node.left.val + " ");
    38                     queue.add(node.left);
    39                 }
    40                 if (node.right != null) {
    41                     System.out.print(node.right.val + " ");
    42                     queue.add(node.right);
    43                 }
    44             }
    45         }
    46     }
    47 
    48     private static TreeNode reConstruct(int[] preorder, int[] inorder) {
    49         if (preorder == null || inorder == null) {
    50             return null;
    51         }
    52 
    53         return reConstructCore(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
    54     }
    55 
    56     private static TreeNode reConstructCore(int[] preorder, int startPre, int endPre,
    57                                             int[] inorder, int startIn, int endIn) {
    58         if (startPre > endPre || startIn > endIn) {
    59             return null;
    60         }
    61 
    62         //获取根节点,先序遍历的第一个值即根节点
    63         TreeNode root = new TreeNode(preorder[startPre]);
    64 
    65         for (int i = startIn; i <= endIn; i++) {
    66             if (inorder[i] == preorder[startPre]) {
    67                 //构建左子树
    68                 root.left = reConstructCore(preorder, startPre + 1, startPre + i - startIn,
    69                         inorder, startIn, i - 1);
    70                 //构建右子树
    71                 root.right = reConstructCore(preorder, i - startIn + startPre + 1, endPre,
    72                         inorder, i + 1, endIn);
    73             }
    74         }
    75 
    76         return root;
    77     }
    78 
    79 
    80 }
    81 
    82 class TreeNode {
    83     int val;
    84     TreeNode left;
    85     TreeNode right;
    86 
    87     TreeNode(int x) {
    88         val = x;
    89     }
    90 }
  • 相关阅读:
    函数参数
    字符编码
    本周内容
    int,float,str,list,dict,元组
    python 基础变量
    Python学习(小笔记一)
    🌐 网络管理
    📓 LVM相关
    📹 进程管理(二)
    🎬进程管理
  • 原文地址:https://www.cnblogs.com/lfeng1205/p/6805436.html
Copyright © 2011-2022 走看看