1.问题描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
2.问题分析
2.1首先了解二叉树的结构
2.2了解二叉树的三种遍历顺序(前序遍历,中序遍历和后序遍历)
前序遍历:中左右
中序遍历:左中右
后序遍历:左右中
根据前序遍历序列和中序遍历序列,或后序遍历序列和中序遍历序列,能唯一确定二叉树。
2.3迭代的编程思想
3.源代码
package www.nowcoder.com.conquerOffer.binaryTree; import java.util.Arrays; /** * 重建二叉树 * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 * http://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking * @author sunny * */ public class BinaryTreeRebuild { /** * 重建二叉树 * @param pre 前序遍历序列数组 * @param in 中序遍历序列数组 * @return 二叉树根节点 */ public TreeNode reConstructBinaryTree(int [] pre,int [] in) { //第一步:校验前序遍历序列或中序遍历序列数组是否为空 if(null == pre || null == in || pre.length <= 0 || in.length <= 0) return null; //第二步:从前序遍历序列中获取根节点的值 int rootVal = pre[0]; //第三步:设置根节点的值 TreeNode rootNode = new TreeNode(rootVal); //第四步:获取根节点在中序遍历序列中的索引值 int rootIndex = findInArray(in, rootVal); //数组工具类自带的二分查找算法 //第五步:获取左子树的前序遍历序列、右子树的前序遍历序列,左子树的中序遍历序列、右子树的中序遍历序列 //左子树的前序遍历序列 int[] preLeft = Arrays.copyOfRange(pre, 1, rootIndex+1); //右子树的前序遍历序列 int[] preRight = Arrays.copyOfRange(pre, rootIndex+1, pre.length); //左子树的中序遍历序列 int[] inLeft = Arrays.copyOfRange(in, 0, rootIndex); //右子树的中序遍历序列 int[] inRight = Arrays.copyOfRange(in, rootIndex+1, pre.length); BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild(); //第六步:构建左子树和右子树 TreeNode leftTree = binaryTreeRebuild.reConstructBinaryTree(preLeft, inLeft); TreeNode rightTree = binaryTreeRebuild.reConstructBinaryTree(preRight, inRight); //第七步:设置根节点的左子树和右子树 rootNode.setLeft(leftTree); rootNode.setRight(rightTree); return rootNode; } /** * 获取数组中目标的下标 * @param arr 数组 * @param target 查找的目标 * @return */ private static int findInArray(int[] arr, int target) { //数组为空 if(null == arr || arr.length <= 0) return -1; for(int i = 0; i < arr.length; i++){ if(target == arr[i]) return i; } return -1; } public static void main(String[] args) { //前序遍历序列 int[] pre = new int[]{1,2,4,7,3,5,6,8}; //中序遍历序列 int[] in = new int[]{4,7,2,1,5,3,8,6}; BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild(); TreeNode rootNode = binaryTreeRebuild.reConstructBinaryTree(pre, in); System.out.println(rootNode); } } /** * 二叉树节点 * @author sunny * */ class TreeNode { int val; //节点值 TreeNode left; //左子树 TreeNode right; //右子树 TreeNode(int x) { val = x; } //构造函数 //左子树的set方法 public void setLeft(TreeNode left) { this.left = left; } //右子树的set方法 public void setRight(TreeNode right) { this.right = right; } }
4.运行效果
1 [email protected]
运行效果
时间: 2024-11-03 21:18:49