剑指Offer之重建二叉树
2017-05-04 09:53
369 查看
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。分析:
在二叉树的前序遍历中,第一个数字总是树的根节点的值。但在中序遍历序列中,根节点的值在序列的中间,左子树的值位于根节点的左边,而右子树的节点的值位于根节点的值得右边。因此我们需要扫描中序遍历,才能找到根节点的值。如下图所示,前序遍历序列的第一个数字1就是根节点的值。扫描中序遍历序列,就能确定根节点的值得位置。根据中序遍历特点,在根节点的值1前面的3个数字都是左子树节点的值,位于1后面的数字都是右子树节点的值。
![](https://images2015.cnblogs.com/blog/997228/201705/997228-20170504094540242-1098544905.png)
由于在中序遍历中,有3个数字是左子树节点的值,因此左子树总共有3个左子节点。同样,在前序遍历中,根节点后面的3个数字就是3个左子树节点的值,再后面的所有数字都是右节点的值。这样我们就在前序遍历和中序遍历两个序列中,分别找到了左右子树对应的子序列。
Java代码
import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; /** * Created by Feng on 2017/5/1. * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 * 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 */ public class ReConstructBinaryTree { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt();//二叉树的节点数 int[] preorder = new int ;//二叉树先序遍历 for (int i = 0; i < n; i++) { preorder[i] = sc.nextInt(); } int[] inorder = new int ;//二叉树中序遍历 for (int i = 0; i < n; i++) { inorder[i] = sc.nextInt(); } TreeNode root = reConstruct(preorder, inorder); System.out.print(root.val + " "); //使用对列输出重构的二叉树 Queue<TreeNode> queue = new LinkedList<>(); queue.add(root); //利用对列先进先出的特点 while (!queue.isEmpty()) { TreeNode node = queue.poll(); if (node.left != null) { System.out.print(node.left.val + " "); queue.add(node.left); } if (node.right != null) { System.out.print(node.right.val + " "); queue.add(node.right); } } } } private static TreeNode reConstruct(int[] preorder, int[] inorder) { if (preorder == null || inorder == null) { return null; } return reConstructCore(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); } private static TreeNode reConstructCore(int[] preorder, int startPre, int endPre, int[] inorder, int startIn, int endIn) { if (startPre > endPre || startIn > endIn) { return null; } //获取根节点,先序遍历的第一个值即根节点 TreeNode root = new TreeNode(preorder[startPre]); for (int i = startIn; i <= endIn; i++) { if (inorder[i] == preorder[startPre]) { //构建左子树 root.left = reConstructCore(preorder, startPre + 1, startPre + i - startIn, inorder, startIn, i - 1); //构建右子树 root.right = reConstructCore(preorder, i - startIn + startPre + 1, endPre, inorder, i + 1, endIn); } } return root; } } class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }
相关文章推荐
- 牛客_剑指offer_重建二叉树,再后续遍历_递归思想_分两端
- 剑指offer 重建二叉树
- 【剑指offer】面试题6:重建二叉树
- 剑指offer之重建二叉树
- 剑指Offer--4.重建二叉树
- 剑指offer--4.重建二叉树
- 剑指offer面试题06:重建二叉树
- 剑指offer 2 重建二叉树
- [剑指offer-1385]重建二叉树
- 九度Online Judge | 剑指Offer | 重建二叉树
- [剑指offer]8.重建二叉树
- 剑指offer面试题6--重建二叉树
- 剑指offer-算法题练习:part4 重建二叉树
- 剑指Offer——重建二叉树
- 剑指offer题6_重建二叉树
- (C++)剑指offer-4:重建二叉树(理解不透彻)
- 剑指offer面试题6:重建二叉树
- 剑指offer——重建二叉树
- 剑指offer-重建二叉树