1.考点
- 考点1:二叉树的前中后遍历方式,以及三者独特的特性;
- 考点2:递归的原理辨析(递归三类中的多路递归,就是多叉树结构);
2.解题
- (1)前/后序遍历时,其根节点位于首/尾位置,而其余的字段可以被分成左子树和右子树,而两者的左子树和右子树内部,又可以分为多个左子树和右子树,并且两两分离,不会有穿插。
- (2)中序遍历时,根节点在遍历中间,而左右两侧分别为嵌套的左子树和右子树,与前/后序遍历一样,不会有穿插;
- (3)解题思路:首先从前/后序遍历中取根节点数值,然后依据数值从中序遍历中查找到根节点的位置,最后将划分的前/后序遍历左子树与中序遍历左子树作为递归条件,计算根节点的左子树,右子树同理。
3.代码
- 代码有两个版本,前版本是把计算递归位置的四个起始点与长度的变量写出来了,便于理解;后一个版本去除了一些冗余条件和多余变量,看上去更简洁
#include <iostream>
#include <vector>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution
{
public:
TreeNode * reConstructBinaryTree(const vector<int> &pre,const vector<int> &vin)
{
return reConstructBinaryTree(pre, 0, pre.size() - 1, vin, 0, vin.size() - 1);
}
TreeNode * reConstructBinaryTree1(const vector<int> &pre, int preStart, int preEnd, const vector<int> &vin, int midStart, int midEnd)
{
if (preStart > preEnd || midStart > midEnd)
return NULL;
TreeNode * root = new TreeNode(pre[preStart]);
if (preStart == preEnd)
return root;
int midLeftTreeEnd = 0;
int midRightTreeStart = 0;
int leftTreeSize = 0;
int rightTreeSize = 0;
for (int i = midStart; i <= midEnd; i++)
{
if (vin[i] == root->val)
{
midLeftTreeEnd = i - 1;
midRightTreeStart = i + 1;
leftTreeSize = i - midStart;
rightTreeSize = midEnd - i;
break;
}
}
root->left = reConstructBinaryTree(pre, preStart + 1, preStart + leftTreeSize, vin, midStart, midLeftTreeEnd);
root->right = reConstructBinaryTree(pre, preStart + leftTreeSize + 1, preEnd, vin, midRightTreeStart, midEnd);
return root;
}
TreeNode * reConstructBinaryTree(const vector<int> &pre, int preStart, int preEnd, const vector<int> &vin, int midStart, int midEnd)
{
if (preStart > preEnd || midStart > midEnd)
return NULL;
TreeNode * root = new TreeNode(pre[preStart]);
for (int i = midStart; i <= midEnd; i++)
{
if (vin[i] == root->val)
{
root->left = reConstructBinaryTree(pre, preStart + 1, preStart + i - midStart, vin, midStart, i - 1);
root->right = reConstructBinaryTree(pre, preStart + i - midStart + 1, preEnd, vin, i + 1, midEnd);
break;
}
}
return root;
}
TreeNode* travPos_Recursion(TreeNode* node)
{
if (node == NULL)
return NULL;
cout << node->val << " ";
travPos_Recursion(node->left);
travPos_Recursion(node->right);
}
};
int main()
{
vector<int> pre = { 1,2,4,7,3,5,6,8 };
vector<int> vin = { 4,7,2,1,5,3,8,6 };
Solution s;
s.travPos_Recursion(s.reConstructBinaryTree(pre, vin));
cout << endl;
return 0;
}