二叉树之一
//sicily 1935. 二叉树重建
#include <iostream> //根据先序遍历序列和中序遍历序列建立二叉树,并按层遍历
#include <string>
using namespace std;
string str1,str2;
int n;
struct Node
{
char ch;
Node *left,*right;
}node[5000];
Node* built(int s1,int t1,int s2,int t2) //根据先序遍历序列和中序遍历序列建二叉树
{
int m=n++; //声明为局部变量
node[m].ch=str1[s1];
int mid=str2.find(str1[s1]); //str1[s1]为根结点字符
if(s2<mid)
node[m].left=built(s1+1,s1+mid-s2,s2,mid-1); //递归构造左子树,左子树结点总数是mid-s2
else
node[m].left=NULL;
if(t2>mid)
node[m].right=built(s1+mid-s2+1,t1,mid+1,t2); //递归构造右子树,右子树结点总数是t2-mid
else
node[m].right=NULL;
return &node[m]; //返回根结点指针
}
void bfs(Node *root) //按层遍历
{
Node *col[1000],*temp;
int front=0,rear=0;
col[rear++]=root;
while(front<rear)
{
temp=col[front++];
cout<<temp->ch;
if(temp->left!=NULL)
{
col[rear++]=temp->left;
}
if(temp->right!=NULL)
{
col[rear++]=temp->right;
}
}
cout<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>str1>>str2;
n=0;
Node *root=built(0,str1.size()-1,0,str2.size()-1);
bfs(root);
}
return 0;
}
//在建树过程中当遇到子结点为空时,应该显式地声明 node[m].left=NULL; 或者 node[m].right=NULL;
//之前在 Node的默认构造函数设置 left=right=NULL; 但因为是在node[5000]数组上进行操作,指针指向并不会更新,
//所以只有在第一次输入的时候才是正确的,之后没有遇到空的子结点时,node[m].left(right)其实并不为空,导致错误
//另外,如果在built函数内声明 Node node[5000]; 则每次建树都会默认初始化为 node[i].left=node[i].right=NULL;
//但如此一来,node就是局部变量了,在执行 bfs(root);时 node 已经超出有效范围了,同样导致错误