题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都
不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题:仔细观察重建二叉树,前序遍历和中序遍历规律,前序遍历是存放根节点,中序就是以此节点做切分左右子树!递归是树本质,递归这个时候写出来的代码特美!
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
int vin_size = vin.size();
if (vin_size == 0)
return NULL;
int val = pre[0];//root or subroot
TreeNode* node = new TreeNode(val);
int p = 0;
for (; p<vin_size; p++){
if (vin[p] == val)//root positon
break;
}
//直接初始化,注意容器初始化另外一个容器最好采用偏移位置,不要采用数组[]索引形式传入地址,容器的最后一个地址是end是不给数组形式索引的!
vector<int> vin_left(vin.begin(), vin.begin()+p),\
vin_right(vin.begin() + p + 1, vin.begin()+vin_size),\
pre_left(pre.begin() + 1, pre.begin()+p+1),\
pre_right(pre.begin()+p+1, pre.begin()+vin_size);
//或者采用循环
/*for (int i = 0; i<vin_size; i++){
if (i<p){
vin_left.push_back(vin[i]);
pre_left.push_back(pre[i + 1]);
}
else if (i>p){
vin_right.push_back(vin[i]);
pre_right.push_back(pre[i]);
}
}*/
node->left = reConstructBinaryTree(pre_left, vin_left);//先构造左边
node->right = reConstructBinaryTree(pre_right, vin_right);//接着右边
return node;
}
void printf_middle_order(TreeNode* boot)
{
if (boot != NULL)
{
printf_middle_order(boot->left);
printf("%d ",boot->val);
printf_middle_order(boot->right);
}
}
void printf_pre_order(TreeNode* boot)
{
if (boot != NULL)
{
printf("%d ", boot->val);
printf_middle_order(boot->left);
printf_middle_order(boot->right);
}
}
int main()
{
int pre_shuzu[8] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int vin_shuzu[8] = { 4, 7, 2, 1, 5, 3, 8, 6 };
vector<int> pre(&pre_shuzu[0],&pre_shuzu[8]);//注意vector结束是要数组的最后一个元素的下一个地址
vector<int> vin(&vin_shuzu[0], &vin_shuzu[8]);
TreeNode* tree_boot = reConstructBinaryTree(pre,vin);
printf_middle_order(tree_boot);
while (true)
{
}
return 0;
}