[算法学习]输入遍历重建二叉树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[算法学习]输入遍历重建二叉树相关的知识,希望对你有一定的参考价值。

问题描述:
假设二叉树中的值都不重复,
(1) 输入前序遍历和中序遍历的结果,输出该二叉树;
(2) 输入中序遍历和后序遍历的结果,输出该二叉树。

分析:
(1) 由前序确定根节点,中序确定左右子树范围,然后用递归重复这段逻辑。根据前序遍历可知根节点在第一个的位置,根据这个根节点在中序遍历中的位置,左边是左子树,右边是右子树,然后根据中序遍历的左右子树范围判断出前序遍历中的左右子树,按照这个思路将左右子树当作新的遍历递归就可以。例如:前序遍历{1,2,4,7,3,5,6,8},中序遍历{4,7,2,1,5,3,8,6},由前序遍历知根节点是1,所以由中序知左子树序列是{4,7,2},右子树序列是{5,3,8,6},前序中左子树序列的是{2,4,7},右子树序列是{3,5,6,8}。然后将前序序列中的左子树和中序序列的左子树递归,前序序列中的右子树和中序序列的右子树递归。

(2) 跟(1)同样的思路,由后序确定根节点,中序确定左右子树的范围,然后也是使用递归。


理一理代码思路

(1).

  1. /**
  2. *
  3. * 输入前序+中序
  4. *
  5. * @param first
  6. * @param center
  7. * @return
  8. */
  9. public static TreeNode inputFirstAndCenter(int[] first, int[] center)
  10. {
  11. if (first == null || center == null || first.length != center.length)
  12. {
  13. return null;
  14. }
  15. int root_val = first[0];
  16. TreeNode root = new TreeNode(root_val);
  17. for (int i = 0; i < center.length; i++)
  18. {
  19. if (center[i] == root_val)
  20. {// 这里要很小心,注意处理好边界判断
  21. // 当中序数组第一个为根节点时说明这个根节点没有左子树,如果不是就有左子树
  22. // 前序数组:0是根节点,1~i是左子树,i+1后是右子树
  23. // 中序数组:i是根节点,0~i-1是左子树,i+1后市右子树
  24. // 边界情况是:只有根节点,只有左子树,只有右子树
  25. if (i > 0)
  26. {
  27. root.left = inputFirstAndCenter(
  28. Arrays.copyOfRange(first, 1, i + 1),
  29. Arrays.copyOfRange(center, 0, i));
  30. }
  31. if (i < first.length - 1)
  32. {// 处理边界:中序数组中索引i的值是某一根节点,所以要i+1
  33. root.right = inputFirstAndCenter(
  34. Arrays.copyOfRange(first, i + 1, first.length),
  35. Arrays.copyOfRange(center, i + 1, center.length));
  36. }
  37. return root;
  38. }
  39. }
  40. // 输入的序列不匹配
  41. return null;
  42. }

(2).

  1. /**
  2. * 输入中序和后序
  3. *
  4. * @param center
  5. * @param last
  6. * @return
  7. */
  8. public static TreeNode inputCenterAndLast(int[] center, int[] last)
  9. {
  10. if (last == null || center == null || last.length != center.length)
  11. {
  12. return null;
  13. }
  14. int root_val = last[last.length - 1];
  15. TreeNode root = new TreeNode(root_val);
  16. for (int i = 0; i < center.length; i++)
  17. {
  18. if (center[i] == root_val)
  19. {// 这里要很小心,注意处理好边界判断
  20. // 后序数组:length-1是根节点,0~i-1是左子树,i~length-2后是右子树
  21. // 中序数组:i是根节点,0~i-1是左子树,i+1后市右子树
  22. // 边界情况是:只有根节点,只有左子树,只有右子树
  23. if (i > 0)
  24. {
  25. root.left = inputCenterAndLast(
  26. Arrays.copyOfRange(center, 0, i),
  27. Arrays.copyOfRange(last, 0, i));
  28. }
  29. if (i < center.length - 1 && center.length > 1)
  30. {
  31. root.right = inputCenterAndLast(
  32. Arrays.copyOfRange(center, i + 1, center.length),
  33. Arrays.copyOfRange(last, i, last.length - 1));
  34. }
  35. return root;
  36. }
  37. }
  38. // 输入的序列不匹配
  39. return null;
  40. }




以上是关于[算法学习]输入遍历重建二叉树的主要内容,如果未能解决你的问题,请参考以下文章

[算法题] 重建二叉树

每日一道算法题04:重建二叉树

算法之重建二叉树

算法系列——重建二叉树

算法入门06重建二叉树

算法系列—— 重建二叉树