题目就不说了,百度上一大堆,中文版英文版都有,下面分享一下紫书作者的解法,个人觉得可以学习的地方很多:
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
//(11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
struct node
{
bool hv; //have value
int data;
node *left,*right;
};
node* root;
bool failed=false;
node* newnode()
{
node* p;
p=(node*)malloc(sizeof(node));
if(p!=NULL)
{
p->hv=false;
p->left=p->right=NULL;
}
return p;
}
void addnode(int k,char* c)
{
node* p=root;
while(*c)
{
if(*c=='L')
{
if(p->left==NULL)
p->left=newnode();
p=p->left;
}
else if(*c=='R')
{
if(p->right==NULL)
p->right=newnode();
p=p->right;
}
else
break;
c++;
}
if(p->hv==false)
p->data=k;
else
failed=true;
p->hv=true; //DON'T FORGET TO SET HV TO TRUE!!!
}
void remove_tree(node* root)
{
if(root!=NULL)
{
remove_tree(root->left);
remove_tree(root->right);
free(root);
}
}
int init()
{
//return 0: no end-of-input
//return 1: input ended successfully
char s[300];
remove_tree(root);
root=newnode();
while(scanf("%s",s) == 1)
{
if(strcmp(s,"()")==0)
return 1;
int d;
sscanf(&s[1],"%d",&d);
addnode(d,strchr(s,',')+1);
}
return 0;
}
int bfs()
{
node* queue[300];
int front,rear,out[300],t=0;
queue[front=rear=1]=root;
while(front<=rear)
{
node* p=queue[front];
if(p->hv==false)
return 0;
out[++t]=p->data;
if(p->left!=NULL)
queue[++rear]=p->left;
if(p->right!=NULL)
queue[++rear]=p->right;
front++;
}
for(int i=1; i<=t; i++)
cout << out[i] <<" " ;
cout << endl;
return 1;
}
int main()
{
while(init()==1)
{
if(!bfs())
failed=true;
if(failed)
cout << "-1" << endl;
}
return 0;
}
大体思路就是采用链表的方式模拟建了一个二叉树。
1.在第29行使用了了while()循环的特殊用法,笔者在python中曾经见过这种用法,今天在C++有幸能看到,不得不说C++永无止境。
一种切片思想吧,比如第一组测试数据(11,LL),addnode(K=11,*c=“LL)”),如果是我,我会写一个char temp;然后for循环依次赋值,遇到‘)’break;但是运用切片思想一条while(*c)直接写出了我所有思想。
2.在第75行灵活运用了指针,原来一直并坚信,scanf输入字符串没有取地址符,第一眼看到这里还以为写错了,连忙跑了一下样例,才仔细审视这句话是什么意思,仔细想了一下有了自己的想法,但并不知道科不科学,在这里说一下吧:
字符串本身就是一个地址,那么地址的地址是什么,没错,就是一个字符,可以用二级指针理解,所以&s[1]就是定位到字符串的第二个字符的地址,那么sscanf的形参接受到一个地址,会自动往下寻找,字符串的缘故嘛。不得不说,指针灵活使用真的是太强大了。