题意略
个人的弱点在于读入的字符如何转换的问题。这个代码里的read函数值得思考。
两种建树方式,一种是工程上常用的指针,一种是竞赛里常用的数组。指针调试稍微复杂点,容易出错。数组较为方便。
Input:
(11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
(3,L) (4,R) ()
(1,) ()
Output:
5 4 8 11 13 4 7 2 1
not complete
1
指针版本:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <string>
using namespace std;
#define pb push_back
#define fi first
#define se second
const int maxn = 1e5;
char s[maxn];
struct Node{
bool have_value;
int v;
Node *left, *right;
Node():have_value(false),left(NULL),right(NULL){};
};
Node* root;
Node* newnode(){
return new Node();
}
bool failed;
void addnode(int v, char *s){
int n = strlen(s);
Node* u = root;
for(int i=0; i<n; ++i){
if(s[i] == 'L'){
if(u->left == NULL) u->left = newnode();
u = u->left;
}else if(s[i] == 'R'){
if(u->right == NULL) u->right = newnode();
u = u->right;
}
}
if(u->have_value) failed = true;
u->v = v;
u->have_value = true;
}
void remove_tree(Node* u){
if(u == NULL) return;
remove_tree(u->left);
remove_tree(u->right);
delete u;
}
bool read_input(){
failed = false;
remove_tree(root);
root = newnode();
while(1){
if(scanf("%s",s) != 1) return false;
if(!strcmp(s,"()")) break;
int v;
sscanf(&s[1],"%d",&v);
addnode(v,strchr(s, ',')+1); //strchr返回第一次出现字符的位置(地址)
}
return true;
}
bool bfs(vector<int> &ans){
queue<Node*> q;
ans.clear();
q.push(root);
while(!q.empty()){
Node* u = q.front(); q.pop();
if(!u->have_value) return false;
ans.pb(u->v);
if(u->left != NULL) q.push(u->left);
if(u->right != NULL) q.push(u->right);
}
return true;
}
int main(){
vector<int> ans;
while(read_input())
{
if(failed || !bfs(ans)){
puts("not complete");
continue;
}
for(auto it=ans.begin(); it!=ans.end(); ++it){
printf("%d",*it);
if(it!=ans.end()-1){
putchar(' ');
}
}
puts("");
}
return 0;
}
数组版本:原书上的newnode函数有误,更正见代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
#define pb push_back
#define fi first
#define se second
const int maxn = 1<<10;
bool failed;
const int root = 1;
int cnt = 1;
int left[maxn];
int right[maxn]; //left 和 right 是iostream里的关键字,不要加这个头文件。
bool have_value[maxn];
int value[maxn];
void newtree(){
left[root] = right[root] = 0; //初始指向0,表示没有子树
have_value[root] = false;
cnt = 1;
}
int newnode(){
int u = ++cnt;
left[u] = right[u] = 0;
have_value[u] = false; //书上原句是have_value[root] = false; 显然错误,是u而不是root
return u;
}
void addnode(int v,char* ss){
int n = strlen(ss);
int u = root;
for(int i=0; i<n; ++i){
if(ss[i] == 'L'){
if(left[u] == 0){
left[u] = newnode();
}
u = left[u];
}else if(ss[i] == 'R'){
if(right[u] == 0){
right[u] = newnode();
}
u = right[u];
}
}
if(have_value[u]) failed = true;
value[u] = v;
have_value[u] = true;
}
char s[maxn];
bool read_input(){
failed = false;
newtree();
while(1){
if(scanf("%s",s) != 1) return false;
if(!strcmp(s,"()")) break;
int v;
sscanf(&s[1],"%d",&v);
addnode(v,strchr(s, ',')+1); //strchr返回第一次出现字符的位置(地址)
}
return true;
}
bool bfs(vector<int> &ans){
queue<int> Q;
ans.clear();
Q.push(root);
while(!Q.empty()){
int u = Q.front(); Q.pop();
if(!have_value[u]) return false;
ans.pb(value[u]);
if(left[u] != 0) Q.push(left[u]);
if(right[u] != 0) Q.push(right[u]);
}
return true;
}
int main(){
vector<int> ans;
while(read_input()){
if(failed || !bfs(ans)){
puts("not complete");
continue;
}
for(auto it=ans.begin(); it!=ans.end(); ++it){
printf("%d",*it);
if(it!=ans.end()-1){
putchar(' ');
}
}
puts("");
}
return 0;
}