二叉树重建(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 }
测试结果: