1.遍历介绍
前序遍历:根节点->左节点->右节点,左子树遍历完才会遍历右子树。
中序遍历:左节点->根节点->右节点
后序遍历:左节点->右节点->根节点
在一个二叉树中节点值都不相同的情况下,前序遍历的第一个节点就是根节点,在中序遍历中找到根节点,在根节点访问之前的节点都属于左子树,在根节点访问之后的节点都属于右子树。由此可知左子树和右子树分别有多少节点。
由于子树的节点的数量与遍历方式无关,通过中序遍历得知左子树和右子树的节点数量和根节点后,可以根据节点数量在前序遍历中得到左子树和右子树的分界。因此可以进一步得到左子树和有子树各自的前序遍历和中序遍历。
2.题目
1.重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val = x; }* }*/class Solution {public TreeNode build(int[] preorder, int[] inorder){if (preorder == null || preorder.length == 0) {return null;}//创建一个存放中序遍历的值,以及每一个值的下标Map<Integer, Integer> indexMap = new HashMap();int length = preorder.length;for (int i = 0; i < length; i++) {indexMap.put(inorder[i], i);}TreeNode root = buildTree(preorder, 0, length - 1, inorder, 0, length - 1, indexMap);return root;}/**** @param preorder 总的前序遍历的数组* @param preorderStart 子前序遍历的第一位在总的前序遍历的下标* @param preorderEnd 子前序遍历的最后一位在总的前序遍历的下标* @param inorder 总的中序遍历* @param inorderStart 子中序遍历的第一位在总的中序遍历的下标* @param inorderEnd 子中序遍历的最后一位在总的中序遍历的下标* @param indexMap 存放中序遍历中的每一个值和它的下标* @return*/public TreeNode buildTree(int[] preorder, int preorderStart, int preorderEnd, int[] inorder, int inorderStart, int inorderEnd, Map<Integer, Integer> indexMap) {if (preorderStart > preorderEnd) {return null;}int rootVal = preorder[preorderStart];TreeNode root = new TreeNode(rootVal);//如果子前序第一个下标和最后一个下标一致,则认为该根节点没有子节点if (preorderStart == preorderEnd) {return root;} else {int rootIndex = indexMap.get(rootVal);int leftNodes = rootIndex - inorderStart;int rightNodes = inorderEnd - rootIndex;TreeNode leftSubtree = buildTree(preorder, preorderStart + 1, preorderStart + leftNodes, inorder, inorderStart, rootIndex - 1, indexMap);TreeNode rightSubtree = buildTree(preorder, preorderEnd - rightNodes + 1, preorderEnd, inorder, rootIndex + 1, inorderEnd, indexMap);root.left = leftSubtree;root.right = rightSubtree;return root;}}}

