二叉树之一

//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 已经超出有效范围了,同样导致错误

  

posted on 2011-08-24 16:25  sysu_mjc  阅读(130)  评论(0编辑  收藏  举报

导航