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

问题描述:

假设二叉树中的值都不重复,

(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. }

来自为知笔记(Wiz)

时间: 2024-11-06 02:19:33

[算法学习]输入遍历重建二叉树的相关文章

二叉树(15)----由中序遍历和后序遍历重建二叉树,递归方式

1.二叉树定义 typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t; 2.由中序遍历和后序遍历重建二叉树 中序遍历中,根节点总是位于左右子树

前序遍历和中序遍历重建二叉树

对于二叉树,在此我不做过多讲解,如有不懂,请参照一下链接点击打开链接 1.在此二叉树的定义: struct BinaryTreeNode     {         BinaryTreeNode<T> *_Left;         BinaryTreeNode<T> *_Right;         T _data;     public:         BinaryTreeNode(const T& x)             :_Left(NULL)       

根据先序遍历中序遍历重建二叉树

根据先序遍历和中序遍历的特点,我们想到了采用递归的方法来实现. 思路:1) 代码的容错性检查,比如:先序遍历和中序遍历长度应相等 2) 先保存先序遍历的第一个点,这个点为结点,接下来循环中序遍历,直到midOrd[index]=该结点,那么接下来就可以采用递归,分别对结点左边和右边的序列采用相同的方法. 3) 直到中序遍历中的序列中只含一个点,整个过程结束. 下面是我写的代码,一直显示错误,不知道什么原因. // 先序中序重建二叉树.cpp : Defines the entry point f

笔试算法题(36):寻找一棵二叉树中最远节点的距离 &amp; 根据二叉树的前序和后序遍历重建二叉树

出题:求二叉树中距离最远的两个节点之间的距离,此处的距离定义为节点之间相隔的边数: 分析: 最远距离maxDis可能并不经过树的root节点,而树中的每一个节点都可能成为最远距离经过的子树的根节点:所以计算出以每个节点为根节点的子树的最 远距离,最后取他们的最大值就是整棵树的最远距离: 如果递归层次过多造成系统栈溢出,则可以使用stack堆栈结构存储递归节点,从而使用循环实现 解题: 1 struct Node { 2 int value; 3 Node *left; 4 Node *right

根据二叉树的前序遍历和中序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(

二叉树(14)----由前序遍历和中序遍历重建二叉树

1.二叉树定义 typedef struct BTreeNodeElement_t_ { void *data; } BTreeNodeElement_t; typedef struct BTreeNode_t_ { BTreeNodeElement_t *m_pElemt; struct BTreeNode_t_ *m_pLeft; struct BTreeNode_t_ *m_pRight; } BTreeNode_t; 二.根据前序遍历序列和中序遍历序列重建二叉树 算法说明: 由中序遍历序

剑指Offer 通过中序和先序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 写一个reConstruct函数4个形参,分别记录子树前序开始结束的位置,中序开始结束的位子.每次在中序中将前序的根节点找出,讲中序分为前(左子树),后(右子树)2 个部分.递归,直到,子树的开始位置大于结束位置. AC代码: 1 /** 2

(难)【07】根据前序,中序遍历重建二叉树

题目 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. input : 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = [9,3,15,20,7] 思路 这道题我不会做,看了题解之后,才发现有迹可循.可以使用递归. 具体思路我会在代码中注释 收获 递归重建二叉树 代码: /** * Definition for a binary tree node. * public class TreeNo

一步两步学算法之中序遍历线索二叉树

1 typedef enum 2 { 3 SubTree, //子树 4 Thread //线索 5 }NodeFlag; 6 7 typedef struct ThreadTree 8 { 9 DATA data; 10 NodeFlag lflag; 11 NodeFlag rflag; 12 struct ThreadTree *left; 13 struct ThreadTree *right; 14 }ThreadBinTree; 15 16 ThreadBinTree *Previo