NKoj1751

题目大意:给出后缀表达式序列,求出层次遍历的结果

解决:还原树的形状,bfs之后就是结果,先直接开辟树结点数组,将数据导入结点,然后寻找节点间父子关系,从而完成建树过程

ac代码: 

 1 #include <iostream>
2 #include <cctype>
3 #include <queue>
4 #include <string>
5 #include <vector>
6 using namespace std;
7 string str;
8 struct node
9 {
10 char data;
11 bool mark;
12 node*lch,*rch;
13 };
14 node *root=NULL;
15 node tree[10005];
16 //树的层次遍历过程
17 void bfs(int n)
18 {
19 node *root=&tree[n-1];
20 queue<node*> q;//结点指针的队列
21 vector<char> v(n);//放结果的数组
22 int t=0;
23 node* tmp;
24 q.push(root);
25 while(!q.empty())
26 {
27 v[t++]=q.front()->data;
28 tmp=q.front();
29 q.pop();
30 if(tmp->lch)q.push(tmp->lch);
31 if(tmp->rch)q.push(tmp->rch);
32 }
33 for(int i=n-1;i>=0;i--)cout<<v[i];
34 cout<<endl;
35
36 }
37 void creat(string str)
38 {
39 int len=str.size();
40 for(int i=0;i<len;i++){tree[i].data=str[i];tree[i].lch=tree[i].rch=NULL;tree[i].mark=0;}
41 int pos=0,t=0,n=len;
42 while(n!=1)
43 {
44 while(islower(str[pos])){t++;pos++;}
45 int i=t-1;
46 while(tree[i].mark)i--;
47 tree[t].rch=&tree[i];
48 tree[i].mark=1;i--;
49 while(tree[i].mark)i--;
50 tree[t].lch=&tree[i];
51 tree[i].mark=1;
52 n-=2;
53 str.erase(pos-2,2);
54 t++;
55 pos--;
56 }
57 bfs(len);
58 }
59 int main()
60 {
61
62 int icase;
63 cin>>icase;
64 while(icase--)
65 {
66 cin>>str;
67 creat(str);
68 }
69 // system("pause");
70 return 0;
71 }

未ac代码总结:

#include <iostream>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
using namespace std;
string str;
struct node
{
    char data;
    node*lch,*rch;
    node(){lch=rch=NULL;}
};
node *root=NULL;
node tree[10005];
void bfs(int n)
{
    node *root=&tree[n-1];
    queue<node*> q;
    vector<char> v(n);
    int t=0;
    node* tmp;
    q.push(root);
    while(!q.empty())
    {
        v[t++]=q.front()->data;
        tmp=q.front();
        q.pop();
/ *下边两行纠结了很久,原来是手误,应该是结点非空是进入队列,应该是
    if(tmp->lch)q.push(tmp->lch);
    if(tmp->rch)q.push(tmp->rch);
*/
        if(!tmp->lch)q.push(tmp->lch);
        if(!tmp->rch)q.push(tmp->rch);
    }
    for(int i=n-1;i>=0;i--)cout<<v[i];
    cout<<endl;
    
}
void creat(string str)
{
    int len=str.size();
/* 由于是多组数据,每次必须初始化,所以一次初始化工作是不够的,
 下边这行不行,开辟数组是也不用一次初始化,只需在此处修改为
for(int i=0;i<len;i++)
{
  tree[i].data=str[i];
  tree[i].lch=treee[i].rch=NULL;//孩子结点初始化
 tree[i].mark=false;//标志域初始化
}
*/
    for(int i=0;i<len;i++)tree[i].data=str[i];
    int pos=0,t=0;
    while(len!=1)
    {
        while(islower(str[pos])){t++;pos++;}
  /*下边的根节点可以用t,但是左子树不是t-1,而是左边没用过的第一个和第二个元素
   而且不一定是紧邻的,这是我可以为每个结点定义一个标志mark,用过了就打上标记
  然后用while循环找到子节点即可  */
        tree[t].rch=&tree[t-1];
        tree[t].lch=&tree[t-2];
        len-=2;//len已经改变,下边将len传入一定为1,应该在上边在定义一个变量等于len
        str.erase(pos-2,2);
        t++;
        pos--;//pos一定是减,因为我一次删除了两个字符pos是字符的下标,变大了要减去
    }
    bfs(len);
}
int main()
{
    
    int icase;
    cin>>icase;
    while(icase--)
    {
        cin>>str;
        creat(str);
    }
    system("pause");
    return 0;
}

posted on 2011-08-04 08:11  猿类的进化史  阅读(439)  评论(0编辑  收藏  举报