输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
1、二叉树相关
1.1、二叉树节点定义
typedef struct TreeNode
{
int val;
struct TreeNode *left;
struct TreeNode *next;
}TNode;
1.2、二叉树前序遍历
void preOrder(TNode *node)
{
if(!node)
return;
cout<<node->val<<" ";
preOrder(node->left);
preOrder(node->right);
}
1.3、二叉树中序遍历
void inOrder(TNode *node)
{
if(!node)
return;
inOrder(node->left);
cout<<node->val<<" ";
inOrder(node->right);
}
1.4、二叉树后序遍历
void posOrder(TNode *node)
{
if(!node)
return;
posOrder(node->left);
posOrder(node->right);
cout<<node->val<<" ";
}
2、根据前序遍历与中序遍历重建二叉树
TNode* reConstructBinaryTree(vector<int> pre,vector<int> in)
{
//如果pre与in任一个为空则返回空
if(pre.empty() || in.empty())
return NULL;
//新建结点,以当前前序遍历的第一个值为当前子树根结点的值
TNode *node = new TreeNode();
node->val = pre[0];
//求左子树前序遍历(preLeft)和中序遍历(InLeft)
vector<int> preLeft;
vector<int> InLeft;
int i = 0;
while(pre[0] != in[i] && i < (int)in.size())
{
preLeft.push_back(pre[i+1]);
InLeft.push_back(in[i]);
i++;
}
//求右子树前序遍历(preRight)和中序遍历(InRight)
i++;
vector<int> preRight;
vector<int> InRight;
while(i < (int)in.size())
{
preRight.push_back(pre[i]);
InRight.push_back(in[i]);
i++;
}
//重建左子树
node->left = reConstructBinaryTree(preLeft,InLeft);
//重建右子树
node->right = reConstructBinaryTree(preRight,InRight);
return node;
}
3、演示
#include <vector>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
vector<int> pre = {1,2,4,7,3,5,6,8};
vector<int> in = {4,7,2,1,5,3,8,6};
TNode *pp =reConstructBinaryTree(pre,in);
//前序遍历
cout<<"前序遍历:";
preOrder(pp);
cout<<endl;
//中序遍历
cout<<"中序遍历:";
inOrder(pp);
cout<<endl;
//后序遍历
cout<<"后序遍历:";
posOrder(pp);
cout<<endl;
return 0;
}
输出:
前序遍历:1 2 4 7 3 5 6 8
中序遍历:4 7 2 1 5 3 8 6
后序遍历:7 4 2 5 8 6 3 1