乱搞竟然让我搞出来了.
首先把所有的结点值保存下来排序.
然后从第二行tree[i]开始找tree[i][j] 在第一行tree[i-1]第一个大于tree[i][j]的值.
找到位置之后找左右位置,左右儿子只能是未被选的.如果两个字母在最后的有序序列位置之间还有没有被选的字母(图中的M和H就是这种关系),说明这个左边的字母是不能作为左儿子的,同理右儿子也一样.
每完成一行就把前一行的字母合并到这行再排个序.
#include <cstdio>
#include <iostream>
#include <memory.h>
using namespace std;
struct node{
char v;
node *lc,*rc;
}ns[26];
char treeV[26];
char buf[26];
char tree[26][26];
bool exi[26];//是否存在这个字母
bool vis[26];//是否被选
void postOrder(node * p){
if(p == NULL)return;
else{
printf("%c", p->v);
postOrder(p->lc);
postOrder(p->rc);
}
}
bool isLeagal(char a, char b){
if(a > b)swap(a, b);
for(a += 1;a < b; ++a){
if(!vis[a - 'A'] && exi[a - 'A'] != -1)return false;
}
return true;
}
int main(){
while(1){
memset(ns, 0, sizeof(ns));
memset(treeV, 0, sizeof(treeV));
memset(exi, 0, sizeof(exi));
memset(vis, 0, sizeof(vis));
int idx = 0, level = 0;
while(scanf("%s", buf) && strcmp(buf, "*") && strcmp(buf, "$")){
int len = strlen(buf);
for(int i = 0; i < len; ++i){
treeV[idx++] = buf[i];
}
memcpy(tree[level++], buf, sizeof(buf));
}
sort(treeV, treeV + idx);
int len = strlen(treeV);
for(int i = 0; i < len; ++i){
exi[treeV[i] - 'A'] = 1;
}
for(int i = 1; i < level; ++i){
int len1 = strlen(tree[i - 1]);
int len2 = strlen(tree[i]);
for(int j = 0; j < len2; ++j){
int k = 0;
for(k = 0; k < len1; ++k){//找第一个大于tree[i][j]的字母
if(tree[i][j] < tree[i - 1][k])break;
}
//找左儿子
for(int q = k - 1; q >= 0; --q){
int id1 = tree[i][j] - 'A', id2 = tree[i - 1][q] - 'A';
if(isLeagal(tree[i][j], tree[i - 1][q]) && !vis[id2]){
ns[id2].v = tree[i - 1][q];
vis[id2] = 1;
ns[id1].lc = &ns[id2];
break;
}
}
//找右儿子
for(int q = k; q < len1; ++q){
int id1 = tree[i][j] - 'A', id2 = tree[i - 1][q] - 'A';
if(isLeagal(tree[i][j], tree[i - 1][q]) && !vis[id2]){
ns[id2].v = tree[i - 1][q];
vis[id2] = 1;
ns[id1].rc = &ns[id2];
break;
}
}
}
if(i + 1 != level){
while(len1 > 0){//合并到一行
tree[i][len2++] = tree[i - 1][--len1];
}
sort(tree[i], tree[i] + strlen(tree[i]));
}
}
ns[tree[level - 1][0] - 'A'].v = tree[level - 1][0];
postOrder(&ns[tree[level - 1][0] - 'A']);
printf("\n");
if(strcmp(buf, "$") == 0)break;
}
return 0;
}