1.遍历介绍

前序遍历:根节点->左节点->右节点,左子树遍历完才会遍历右子树。
中序遍历:左节点->根节点->右节点
后序遍历:左节点->右节点->根节点
在一个二叉树中节点值都不相同的情况下,前序遍历的第一个节点就是根节点,在中序遍历中找到根节点,在根节点访问之前的节点都属于左子树,在根节点访问之后的节点都属于右子树。由此可知左子树和右子树分别有多少节点。
由于子树的节点的数量与遍历方式无关,通过中序遍历得知左子树和右子树的节点数量和根节点后,可以根据节点数量在前序遍历中得到左子树和右子树的分界。因此可以进一步得到左子树和有子树各自的前序遍历和中序遍历。

image.png

2.题目

1.重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. class Solution {
  11. public TreeNode build(int[] preorder, int[] inorder){
  12. if (preorder == null || preorder.length == 0) {
  13. return null;
  14. }
  15. //创建一个存放中序遍历的值,以及每一个值的下标
  16. Map<Integer, Integer> indexMap = new HashMap();
  17. int length = preorder.length;
  18. for (int i = 0; i < length; i++) {
  19. indexMap.put(inorder[i], i);
  20. }
  21. TreeNode root = buildTree(preorder, 0, length - 1, inorder, 0, length - 1, indexMap);
  22. return root;
  23. }
  24. /**
  25. *
  26. * @param preorder 总的前序遍历的数组
  27. * @param preorderStart 子前序遍历的第一位在总的前序遍历的下标
  28. * @param preorderEnd 子前序遍历的最后一位在总的前序遍历的下标
  29. * @param inorder 总的中序遍历
  30. * @param inorderStart 子中序遍历的第一位在总的中序遍历的下标
  31. * @param inorderEnd 子中序遍历的最后一位在总的中序遍历的下标
  32. * @param indexMap 存放中序遍历中的每一个值和它的下标
  33. * @return
  34. */
  35. public TreeNode buildTree(int[] preorder, int preorderStart, int preorderEnd, int[] inorder, int inorderStart, int inorderEnd, Map<Integer, Integer> indexMap) {
  36. if (preorderStart > preorderEnd) {
  37. return null;
  38. }
  39. int rootVal = preorder[preorderStart];
  40. TreeNode root = new TreeNode(rootVal);
  41. //如果子前序第一个下标和最后一个下标一致,则认为该根节点没有子节点
  42. if (preorderStart == preorderEnd) {
  43. return root;
  44. } else {
  45. int rootIndex = indexMap.get(rootVal);
  46. int leftNodes = rootIndex - inorderStart;
  47. int rightNodes = inorderEnd - rootIndex;
  48. TreeNode leftSubtree = buildTree(preorder, preorderStart + 1, preorderStart + leftNodes, inorder, inorderStart, rootIndex - 1, indexMap);
  49. TreeNode rightSubtree = buildTree(preorder, preorderEnd - rightNodes + 1, preorderEnd, inorder, rootIndex + 1, inorderEnd, indexMap);
  50. root.left = leftSubtree;
  51. root.right = rightSubtree;
  52. return root;
  53. }
  54. }
  55. }