1.百度百科摘要:
排序之后直接构造笛卡尔树的方法:
首先将节点序列按照key从小到大排序,然后按照顺序插入节点,注意到排序之后,插入的节点的key值一定是树中最大的,所以只需查找最右端的路径,找到一个节点A[i]的value大于待插入节点的value,同时A[i]->right的value小于待插入节点的value。找到之后,只需将A[i]的right指向待插入的节点,A[i]的right原来指向的节点赋值给待插入节点的left指针
2.scanf的用法,%*[ ],表示越过[ ]中的字符,%[a-z]表示读入字符串,直到遇到不是a-z中的字符为止。%[^a]表示读入字符串直到遇到字符a为止,但a并没有被读入。(网上学习)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 55000;
const int maxc = 100;
struct node{
char s[maxc];
int val,l,r,fa;
}dt[maxn];
bool Cmp(node a, node b){ return strcmp(a.s,b.s) < 0; }
void Insert(int i){
int j = i - 1;
while(dt[j].val < dt[i].val) j = dt[j].fa;
dt[i].l = dt[j].r;
dt[i].fa = j;
dt[j].r = i;
}
void Visit(int i){
if(i == 0 ) return ;
printf("(");
Visit(dt[i].l);
printf("%s/%d",dt[i].s,dt[i].val);
Visit(dt[i].r);
printf(")");
}
int main()
{
int n;
while(scanf("%d",&n) == 1 && n){
for(int i = 1; i <= n; ++i){
scanf(" %[a-z]/%d",dt[i].s,&dt[i].val);
dt[i].fa = dt[i].l = dt[i].r = 0;
}
dt[0].fa = dt[0].r = dt[0].l = 0;
dt[0].val = 999999999;
sort(dt+1,dt+n+1,Cmp);
for(int i = 1; i <= n; ++i)
Insert(i);
Visit(dt[0].r);
printf("\n");
}
return 0;
}