数据结构学习之-------树 Trees on the level HDU 1622

来源:互联网 发布:小企业财务会计软件 编辑:程序博客网 时间:2024/04/30 10:10

Trees on the level

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 330    Accepted Submission(s): 114


Problem Description
Trees are fundamental in many branches of computer science. Current state-of-the art parallel computers such as Thinking Machines' CM-5 are based on fat trees. Quad- and octal-trees are fundamental to many algorithms in computer graphics.

This problem involves building and traversing binary trees.
Given a sequence of binary trees, you are to write a program that prints a level-order traversal of each tree. In this problem each node of a binary tree contains a positive integer and all binary trees have have fewer than 256 nodes.

In a level-order traversal of a tree, the data in all nodes at a given level are printed in left-to-right order and all nodes at level k are printed before all nodes at level k+1.

For example, a level order traversal of the tree


is: 5, 4, 8, 11, 13, 4, 7, 2, 1.

In this problem a binary tree is specified by a sequence of pairs (n,s) where n is the value at the node whose path from the root is given by the string s. A path is given be a sequence of L's and R's where L indicates a left branch and R indicates a right branch. In the tree diagrammed above, the node containing 13 is specified by (13,RL), and the node containing 2 is specified by (2,LLR). The root node is specified by (5,) where the empty string indicates the path from the root to itself. A binary tree is considered to be completely specified if every node on all root-to-node paths in the tree is given a value exactly once.

 

Input
The input is a sequence of binary trees specified as described above. Each tree in a sequence consists of several pairs (n,s) as described above separated by whitespace. The last entry in each tree is (). No whitespace appears between left and right parentheses.

All nodes contain a positive integer. Every tree in the input will consist of at least one node and no more than 256 nodes. Input is terminated by end-of-file.

 

Output
For each completely specified binary tree in the input file, the level order traversal of that tree should be printed. If a tree is not completely specified, i.e., some node in the tree is NOT given a value or a node is given a value more than once, then the string ``not complete'' should be printed
 

Sample Input
(11,LL) (7,LLL) (8,R)(5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()(3,L) (4,R) ()
 

Sample Output
5 4 8 11 13 4 7 2 1not complete
 

Source
UVA
这个是刘汝佳白书的例题,其实很简单就是二叉树的建立,最近在从头学数据结构,就尝试着用多种方法来做这道题
1.自己写建立树的函数
    首先得有一个结点的结构体,含有结点数据和左右子节点的指针,然后是逐个逐个地建树,(考虑到输入数据的处理)(还有考虑到树的建立中的一些非法操作)
#include<iostream>#include<string>#include<cstdio>#include<stdlib.h>#include<queue>#define maxn 300using namespace std;typedef struct node{int data;node*l_son;node*r_son;}node;node *root;//这个root 在整个程序中都有用到,可以定义为结构体指针也可以只定义为结构体,但是注意一点,前后要统一,不然改起来费劲!这里指针用起来方便,我就用指针了int fail=0;char s[200];int cnt;int ans[maxn];node*new_node(){node*n=new node;n->l_son=NULL,n->r_son=NULL;//新建的结点的左右儿子必须预先赋空,这也可以作为一个我们判断结点是否赋值的依据!n->data=0;return n;}void remove(node*t)//这个函数我一开始是忘记了的,因为有多组数据,但是我们只利用了一个root结点来建立一棵树,所以在建立下一颗树之前必须先把前一棵树拆了{                         //拆这棵树也是很有技巧的,基于二叉树的递归特性,这里就是对每个结点而言往下拆左子树和右子树,知道当前结点为空!if(t==NULL) return;remove(t->l_son);remove(t->r_son);free(t);}void build(int t,char s[])   //对每一个待插入的数进行插入{node *tem;tem=root;for(int i=0;i<strlen(s);i++){if(s[i]=='L'){if(tem->l_son==NULL){tem->l_son=new_node();}tem=tem->l_son; //千万不要把它写在了循环里面,它是不管原来子节点是否存在,都要往下走的 }else if(s[i]=='R'){if(tem->r_son==NULL){tem->r_son=new_node();}tem=tem->r_son;}}if(tem->data>0)        //这个是判断对于我们找到的结点是否已经赋过值了?如果赋过值了,那就是不对的了fail=1;elsetem->data=t;}int read(){int t;fail=0;remove(root);   //一个read代表着一组数据的输入,所以,将上一组的树要拆掉root=new_node();  //然后初始化 rootwhile(1){if(scanf("%s",s)==EOF) return 0;if(strcmp(s,"()")==0)break;sscanf(&s[1],"%d",&t);      //sscanf(char*(从字符串哪个位置开始输入),"输入格式",const *(输出到哪里))char *s1=strchr(s,',')+1;   //strchr 字符串中的查找函数build(t,s1);}return 1;}int bfs(){cnt=0;queue<node*> q;q.push(root);while(!q.empty()){node *tem=q.front();if(tem->l_son!=NULL)q.push(tem->l_son);if(tem->r_son!=NULL)q.push(tem->r_son);if(tem->data==0)   //这是用来判断有没结点有左右儿子但是没有被赋值的情况(因为我们是从root往下找的,所以就算这个情况也只会是root不满足)return 1;ans[cnt++]=tem->data;q.pop();}return 0;}int main(){freopen("input.txt","r",stdin);while(read()!=0){if(bfs())fail=1;if(fail)cout<<"not complete"<<endl;else{for(int i=0;i<cnt;i++){cout<<ans[i];if(i!=cnt-1)cout<<" ";}cout<<endl;}}} 
以下是用数组来模拟实现二叉树的,虽然对于这个题目而言,因为256点怎么构成二叉树是不清楚的,所以极端情况下,数组必须开到2^256 -1(这是个天文数字)
但是,数组的实现比较容易编码,所以,我也列出来!
#include<iostream>#include<string>#include<cstdio>#define nul -999using namespace std;int tree[100000000];char s[200];int m;int fail;void build(int t,char s[]){int cur=1;int l=strlen(s);for(int i=0;i<strlen(s);i++){if(s[i]=='L')cur=cur*2;else if(s[i]=='R')cur=cur*2+1;if(s[i+1]==')'||s[i]==')'){if(tree[cur]!=-999){fail=1;break;}else{if(cur>m)  //   最大标号的结点显然就是最低层的最右边的那个点m=cur;tree[cur]=t;}break;}}}int read(){int t;while(1){if(scanf("%s",s)==EOF) return 0;if(strcmp(s,"()")==0)break;sscanf(&s[1],"%d",&t);build(t,strchr(s,',')+1);}return 1;}int main(){fail=0;m=1;fill(tree,tree+100000000,nul);freopen("input.txt","r",stdin);while(read()!=0){for(int i=1;i<=m;i++){if(fail) break;if(tree[i]==nul){if(tree[2*i]!=nul||tree[2*i+1]!=nul){fail=1;}}}if(fail)cout<<"not complete"<<endl;else{for(int i=1;i<=m;i++){if(tree[i]==nul)continue;elsecout<<tree[i];if(i!=m)cout<<" ";}cout<<endl;}fail=0;m=1;fill(tree,tree+100000000,nul);}}



0 0
原创粉丝点击