二叉树重建(c++)

题目描述(剑指offer)

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
 
  1 #include <iostream>
  2 #include <vector>
  3 using namespace std;
  4 
  5  // Definition for binary tree
  6 struct TreeNode {
  7       int val;
  8       TreeNode *left;
  9       TreeNode *right;
 10       TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 11 
 12 };
 13 /* 先序遍历第一个位置肯定是根节点node,
 14 中序遍历的根节点位置在中间p,在p左边的肯定是node的左子树的中序数组,p右边的肯定是node的右子树的中序数组
 15 另一方面,先序遍历的第二个位置到p,也是node左子树的先序子数组,剩下p右边的就是node的右子树的先序子数组
 16 把四个数组找出来,分左右递归调用即可
 17  */
 18 
 19 class Solution
 20 {
 21 public:
 22     struct TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin)
 23     {
 24         int in_size = vin.size();//获取序列的长度
 25         if (in_size == 0)
 26             return NULL;
 27 
 28         //分别存储先序序列的左子树,先序序列的右子树,中序序列的左子树,中序序列的右子树
 29         vector<int>pre_left, pre_right, in_left, in_right;
 30 
 31         int val = pre[0];//先序遍历第一个位置是根节点node,取其值
 32         //新建一个树结点,并传入结点值
 33         TreeNode* node = new TreeNode(val);
 34 
 35         //p用于储存中序序列中根节点的位置
 36         int p = 0;
 37         for (p; p < in_size; ++p)
 38         {
 39             if (vin[p] == val)
 40                 break;//找到即跳出for循环
 41         }
 42 
 43         for (int i = 0; i < in_size; ++i)
 44         {
 45             if (i < p)
 46             {
 47                 //建立中序序列的左子树和前序序列的左子树
 48                 in_left.push_back(vin[i]);
 49                 pre_left.push_back(pre[i + 1]);//前序第一个为根节点,+1从下一个开始记录
 50             }
 51             else if(i>p)
 52             {
 53                 //建立中序序列的右子树和前序序列的右子树
 54                 in_right.push_back(vin[i]);
 55                 pre_right.push_back(pre[i]);
 56             }
 57         }
 58 
 59         //取出前序和中序遍历根节点左边和右边的子树
 60         //递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点
 61         node->left = reConstructBinaryTree(pre_left, in_left);
 62         node->right = reConstructBinaryTree(pre_right, in_right);
 63 
 64         return node;
 65     }
 66 
 67 };
 68 
 69 //test=====后序递归遍历二叉树
 70 void Posorder(TreeNode* &T)
 71 {
 72     if (T)//当结点不为空的时候执行
 73     {
 74         //左右中
 75         Posorder(T->left);
 76         Posorder(T->right);
 77         cout << T->val;
 78 
 79     }
 80     else
 81     {
 82         //cout << " ";
 83         T = NULL;
 84     }
 85 }
 86 
 87 int main()
 88 {
 89     vector<int>pre{1,2,4,7,3,5,6,8};
 90     vector<int>vin{4,7,2,1,5,3,8,6};
 91 
 92     Solution T;
 93     TreeNode* node=T.reConstructBinaryTree(pre, vin);
 94 
 95     //测试---输出后续遍历
 96     cout << "后续遍历为:" << endl;
 97     Posorder(node);
 98     cout << endl;
 99 
100     system("pause");    
101 }

测试结果:

posted @ 2018-12-11 16:27  追风少年Vip  阅读(641)  评论(0编辑  收藏  举报