题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
比如说输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出该二叉树。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
struct BinaryTreeNode
{
int data;
BinaryTreeNode *leftchild; //左子树
BinaryTreeNode *rightchild; //右子树
BinaryTreeNode(int n = 0)
{
data = n;
leftchild = NULL;
rightchild = NULL;
}
};
//已知前序和中序重建二叉树
//先序: 根 左 右
//中序: 左 根 右
//后序: 左 右 根
//1.取先序序列第一个值,为根节点即1,在中序遍历查找这个值,那么247为左子树,3568为右子树
//2.然后再继续递归划分,先序247,中序472,那么根节点为2,以此类推。
//重复步骤12然后就可以构造出一棵二叉树了
BinaryTreeNode *PlantTree1(vector<int> pre,vector<int> in)
{
if(pre.size() == 0 ||in.size() == 0||pre.size() != in.size())
{
return NULL; //错误条件
}
BinaryTreeNode *root = new BinaryTreeNode(pre[0]); //先序第一个值为根节点
int index = 0;
vector<int> left_pre,right_pre,left_in,right_in;
//在中序遍历找到 根节点
for(int i = 0; i< (in.size()); i++)
{
if(root->data == in[i])
index = i;
}
for(int i = 0; i < index; i++)
{
left_pre.push_back(pre[i+1]); //根节点左子树前序遍历
left_in.push_back(in[i]); //根节点左子树中序遍历
}
for(int j = index+1; j < pre.size(); j++)
{
right_pre.push_back(pre[j]);
right_in.push_back(in[j]);
}
root->leftchild = PlantTree1(left_pre,left_in);
root->rightchild = PlantTree1(right_pre,right_in);
return root;
}
//已知中序和后序重建二叉树
//先序: 根 左 右
//中序: 左 根 右
//后序: 左 右 根
//1.取后序序列最后一个值,为根节点即1,在中序遍历查找这个值,那么472为左子树,5386为右子树
//2.然后再继续递归划分,中序472,后序742,那么根节点为2,以此类推。
//重复步骤12然后就可以构造出一棵二叉树了
/*
BinaryTreeNode *PlantTree2(vector<int>last,vector<int>in)
{
if(in.size() == 0 ||last.size() == 0 || in.size() != last.size())
{
return NULL;
}
BinaryTreeNode *root = new BinaryTreeNode(last[7]); //先序第一个值为根节点
int index = 0;
vector<int> left_last,right_last,left_in,right_in;
//在中序遍历找到 根节点
for(int i = 0; i< (in.size()); i++)
{
if(root->data == in[i])
index = i;
}
for(int i = 0; i < index; i++)
{
left_last.push_back(last[i]); //根节点左子树前序遍历
left_in.push_back(in[i]); //根节点左子树中序遍历
}
for(int j = index+1; j < in.size(); j++)
{
right_last.push_back(last[j-1]);
right_in.push_back(in[j]);
}
root->leftchild = PlantTree2(left_last,left_in);
root->rightchild = PlantTree2(right_last,right_in);
return root;
}
*/
//先序
void PreorderTraverse(BinaryTreeNode *root)
{
if(root)
{
cout << root->data << ' ';
PreorderTraverse(root->leftchild);
PreorderTraverse(root->rightchild);
}
}
//中序遍历
void InorderTraverse(BinaryTreeNode *root)
{
if(root)
{
InorderTraverse(root->leftchild);
cout << root->data << ' ';
InorderTraverse(root->rightchild);
}
}
//后序
void LastOrderTraverse(BinaryTreeNode *root)
{
if(root)
{
LastOrderTraverse(root->leftchild);
LastOrderTraverse(root->rightchild);
cout << root->data << ' ';
}
}
int main()
{
BinaryTreeNode *root = new BinaryTreeNode(1);
root->leftchild = new BinaryTreeNode(2);
root->rightchild = new BinaryTreeNode(3);
root->leftchild->leftchild = new BinaryTreeNode(4);
root->leftchild->leftchild->rightchild = new BinaryTreeNode(7);
root->rightchild->leftchild = new BinaryTreeNode(5);
root->rightchild->rightchild = new BinaryTreeNode(6);
root->rightchild->rightchild->leftchild = new BinaryTreeNode(8);
vector<int> pre,in,last;
pre.push_back(1);//这棵树的前序遍历
pre.push_back(2);
pre.push_back(4);
pre.push_back(7);
pre.push_back(3);
pre.push_back(5);
pre.push_back(6);
pre.push_back(8);
in.push_back(4);//这棵树的中序遍历
in.push_back(7);
in.push_back(2);
in.push_back(1);
in.push_back(5);
in.push_back(3);
in.push_back(8);
in.push_back(6);
/*
in.push_back(7);//*这棵树的后序遍历
in.push_back(4);
in.push_back(2);
in.push_back(5);
in.push_back(8);
in.push_back(6);
in.push_back(3);
in.push_back(1);
*/
BinaryTreeNode *newroot1 = PlantTree1(pre,in); //通过前序遍历和中序遍历构建一棵树
//BinaryTreeNode *newroot2 = PlantTree2(last,in); //通过前序遍历和中序遍历构建一棵树
cout<<"之前的二叉树先序遍历:";
PreorderTraverse(root);
cout<<endl;
cout<<"之前的二叉树中序遍历:";
InorderTraverse(root);
cout<<endl;
cout<<"之前的二叉树后序遍历:";
LastOrderTraverse(root);
cout<<endl;
cout<<endl;
cout<<"通过前序和中序重建出的二叉树"<<endl;
cout<<"重建后的二叉树前序遍历:";
PreorderTraverse(newroot1);
cout<<endl;
cout<<"重建后的二叉树中序遍历:";
InorderTraverse(newroot1);
cout<<endl;
cout<<"重建后的二叉树中序遍历:";
LastOrderTraverse(newroot1);
cout<<endl;
cout<<endl;
/*
cout<<"通过后序和中序重建出的二叉树"<<endl;
cout<<"重建后的二叉树前序遍历:";
PreorderTraverse(newroot2);
cout<<endl;
cout<<"重建后的二叉树中序遍历:";
InorderTraverse(newroot2);
cout<<endl;
cout<<"重建后的二叉树中序遍历:";
LastOrderTraverse(newroot2);
cout<<endl;
*/
}
牛客网上的AC代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in)
{
if(pre.size() == 0 ||in.size() == 0||pre.size() != in.size())
{
return NULL; //错误条件
}
TreeNode *root = new TreeNode(pre[0]); //先序第一个值为根节点
int index = 0;
vector<int> left_pre,right_pre,left_in,right_in;
//在中序遍历找到 根节点
for(int i = 0; i< (in.size()); i++)
{
if(root->val == in[i])
index = i;
}
for(int i = 0; i < index; i++)
{
left_pre.push_back(pre[i+1]); //根节点左子树前序遍历
left_in.push_back(in[i]); //根节点左子树中序遍历
}
for(int j = index+1; j < pre.size(); j++)
{
right_pre.push_back(pre[j]);
right_in.push_back(in[j]);
}
root->left = reConstructBinaryTree(left_pre,left_in);
root->right = reConstructBinaryTree(right_pre,right_in);
return root;
}
};