您的位置:首页 > 其它

uva122--二叉树的层次遍历

2016-05-20 16:24 399 查看
题意:输入一棵二叉树,输入形式是给定一个结点值和一个字符串,如果字符串时L,则表示该节点在上一层相邻结点的左边,若是R,则表示该节点在上一层相邻结点的右边,若没有字符串则表示该节点就是根节点,字符串和节点值用小括号括起来,并且相邻括号之间都有空格隔开,空括号()则表示输入结束。然后要求你层次输出二叉树结点的值。注意:如果从根节点到某个叶节点的路径有的结点没有给出,或者给出的超过一次,应当输出-1,结点的个数不应该超过256个。input:(11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR)()(3,L) (4,R) ()output:5 4 8 11 13 4 7 2 1-1分析:由于题意中并没有明确指出二叉树是一个满二叉树,而且结点数最大是256个,所以不能考虑将二叉树的结点作为编号放进数组中,不能开那么大的数组,所以只能根据需要建立新的结点,然后再将结点组织成一棵树。首先需要定义一个node 的结构,并对应整棵二叉树的树根root。然后是写个测试函数,测试根节点,左子树和右子树是否为空,再就是重头戏了,建树函数,由于是递归建树,先从根节点开始,如果左子树为空,就建立结点,建树。右子树的操作一样,如果根节点为空,记录下来,并给它赋值,相当于创建结点了。建树过程结束后,就是BFS层次遍历二叉树了,可以将二叉树的结点放进一个数组中去,边放边输,一开始是一个根节点 ,然后输出一个结点,就把它的左右结点(如果存在)都放进去。过程详见代码,最后一步就是主函数的输入了,本题的输入,是将其看成了一个字符串,并且巧妙的运用了sscanf()函数,详细见程序,下面上程序:代码:
#include <bits/stdc++.h>using namespace std;typedef struct node //结点内容{int V;node *L;node *R;}tree;tree node[300];tree *root;int test(tree *root) //测试根节点,和左、右子节点是否为空{if(!root->V) //根节点为空return 0;int ans=0;if(!root->L||test(root->L))ans++;if(!root->R||test(root->R))ans++;return ans==2; //左右子节点为空}int tree_size,complete; //tree_size编号,complete记录结点是否为空int madetree(tree *root,char *str,int v) //建树过程{if(*str=='R'){if(!root->R) //右子树为空,建立结点{root->R=&node[++tree_size];}madetree(root->R,str+1,v); //建树}if(*str=='L'){if(!root->R){root->R=&node[++tree_size];}madetree(root->L,str+1,v);}else{if(root->V)complete=0; //表示根节点不为空root->V=v; //根节点为空的时候就赋值。相当于创建新的结点}}tree *Q[300];void output(tree *root) //层次遍历二叉树{int _move=0,save=0;Q[_move++]=root; //先将根节点放进去cout <<root->V<<endl; //将根结点输出,然后将其左、右子节点放进数组while(_move<save)//一层的结点个数恰好等于输出的左右子节点的个数,即一层输完{tree *now=Q[_move++];if(now->L) //左子结点不为空{cout <<' '<<now->L->V<<endl; //输出左子结点的的值Q[save++]=now->L;//并将其放入数组中}if(now->R){cout <<' '<<now->R->V<<endl;Q[save++]=now->R;}}cout <<endl; //输完二叉树的一层换行}int main(){char buf[256],leaf[256];int value;complete=1; //初始化root=&node[tree_size=0];while(~scanf("%s",buf)){if(!strcmp(buf,"()")){if(!complete||!test(root)){cout <<"no complete."<<endl;}else{output(root);}memset(node ,0,sizeof(node));complete=1;root=&node[tree_size=0];}else{sscanf(buf,"(%d,%s",&value,leaf); //强大的sscanf(),详细见小结madetree(root,leaf,value);}}return 0;}
小结:本题十分重要,也是挺难得,这个题是我看着书写都感觉挺费劲的,要经常回来看这个题。sscanf()函数的应用:例子:  1. 常见用法。  char buf[512] = ;  sscanf("123456 ", "%s", buf);  printf("%s\n", buf);  结果为:123456  2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。  sscanf("123456 ", "%4s", buf);  printf("%s\n", buf);  结果为:1234  3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。  sscanf("123456 abcdedf", "%[^ ]", buf);  printf("%s\n", buf);  结果为:123456  4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。  sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);  printf("%s\n", buf);  结果为:123456abcdedf  5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。  sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);  printf("%s\n", buf);  结果为:123456abcdedf  6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中  sscanf("iios/12DDWDFF@122", "%*[^/]/%[^@]", buf);  printf("%s\n", buf);  结果为:12DDWDFF  7、给定一个字符串““hello, world”,仅保留world。(注意:“,”之后有一空格)  sscanf(“hello, world”, "%*s%s", buf);  printf("%s\n", buf);  结果为:world
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: