simplify # trees: Catalan trees -> Wedderburn–Etherington trees

This commit is contained in:
2021-01-25 10:12:45 +01:00
parent 684c33f156
commit 507988a93b
8 changed files with 203 additions and 76 deletions

146
tree.c
View File

@@ -194,41 +194,49 @@ NODE *dup_node(src)
return dst;
}
/*void free_node(node)
/* untested - unused */
int calc_prof_node(node)
NODE *node;
{
int left, right;
if (node->type==TREE_LEAF) {
node->next=freenodes;
freenodes=node;
return 0;
} else {
free_node(node->left);
free_node(node->right);
node->next=freenodes;
freenodes=node;
left=calc_prof_node(node->left);
right=calc_prof_node(node->right);
node->prof=MAX(left, right)+1;
}
}*/
return node->prof;
}
NODE *build_tree(desc, size)
int *desc;
char *desc;
int size;
{
NODE *root, *node;
NODE *nodestack[1024]; /* TODO: make it dynamic */
int i, curnode=0;
# ifdef DEBUG_TREE
printf("tree %d desc=", ntrees);
for (i=0; i<size; ++i)
printf("%c", desc[i]);
putchar('\n');
# endif
root=get_node();
root->type=TREE_NODE;
nodestack[curnode++]=root;
for(i=1; i<size; ++i) {
node = get_node();
if (desc[i-1]) {
if (desc[i-1]=='1') {
nodestack[curnode-1]->left = node;
} else {
nodestack[curnode-1]->right = node;
curnode--;
}
if (desc[i]) {
if (desc[i]=='1') {
node->type=TREE_NODE;
nodestack[curnode++]=node;
} else {
@@ -239,25 +247,102 @@ NODE *build_tree(desc, size)
return root;
}
void gen_tree(seq, n, nb1, nb0)
int *seq;
int n; /* number of nodes */
int nb1; /* number of "1" */
int nb0; /* number of "0" */
/* generate reduced trees from static description */
void gen_reduced_trees(n)
int n;
{
int size=n*2-1, i;
TREE *tree;
char name[80];
char *seq2[]= {
"100"
};
char *seq3[]= {
"10100"
};
char *seq4[]= {
"1010100",
"1100100"
};
char *seq5[]= {
"101010100",
"110010100",
"101100100"
};
char *seq6[]= {
"10101010100",
"11001010100",
"10110010100",
"10101100100",
"11001100100",
"11010010100"
};
if (n<2 || n>MAXINPUT) {
fprintf(stderr, "gen_reduced_trees: wrong leaves %d\n", n);
return;
}
# ifdef DEBUG_TREE
printf("gen_reduced_trees(leaves=%d)\n", n);
# endif
switch (n) {
case 2:
ntrees++;
sprintf(name, "Tree %d", ntrees);
tree=new_tree(name);
tree->head=build_tree(seq2[0], size);
break;
case 3:
ntrees++;
sprintf(name, "Tree %d", ntrees);
tree=new_tree(name);
tree->head=build_tree(seq3[0], size);
break;
case 4:
for (i=0; i<2; ++i) {
ntrees++;
sprintf(name, "Tree %d", ntrees);
tree=new_tree(name);
tree->head=build_tree(seq4[i], size);
}
break;
case 5:
for (i=0; i<3; ++i) {
ntrees++;
sprintf(name, "Tree %d", ntrees);
tree=new_tree(name);
tree->head=build_tree(seq5[i], size);
}
break;
case 6:
for (i=0; i<6; ++i) {
ntrees++;
sprintf(name, "Tree %d", ntrees);
tree=new_tree(name);
tree->head=build_tree(seq6[i], size);
}
break;
}
return;
}
void gen_tree(seq, n, nb1, nb0)
char *seq;
int n; /* number of nodes */
int nb1; /* number of "1" */
int nb0; /* number of "0" */
{
int i;
char name[80];
TREE *tree;
if((nb1 + nb0) == 2*n) { /* end */
seq[2*n] = 0;
# ifdef DEBUG_TREE
printf("gen_tree(n=%d, nb1=%d, nb0=%d)\n", n, nb1, nb0);
# endif
if((nb1 + nb0) == 2*n) { /* end */
seq[2*n] = '0';
seq[2*n+1] = 0;
ntrees++;
# ifdef DEBUG1
printf("tree %d desc=", ntrees);
for (i=0; i<=2*n; ++i)
printf("%d", seq[i]);
putchar('\n');
# endif
sprintf(name, "Tree %d", ntrees);
tree=new_tree(name);
tree->head=build_tree(seq, 2*n+1);
@@ -265,12 +350,12 @@ void gen_tree(seq, n, nb1, nb0)
}
if(nb1 >= nb0 && nb1 < n) {
seq[nb1+nb0] = 1;
seq[nb1+nb0] = '1';
gen_tree(seq, n, nb1+1, nb0);
}
if(nb0 < nb1 && nb1 <=n) {
seq[nb1+nb0] = 0;
seq[nb1+nb0] = '0';
gen_tree(seq, n, nb1, nb0+1);
}
}
@@ -292,13 +377,13 @@ int n_trees()
}
#ifdef STANDALONE
main(ac, av)
void main(ac, av)
int ac;
char **av;
{
int n, details=0;
char array[1024];
int array[1024];
if (ac<2 || ac>3) {
fprintf(stderr, "usage: %s nodes [type]\n", *av);
fprintf(stderr, "type can be 0 (RPN, default, 1 (polish), 2 (details), 3 (lisp notation), 4 (parenthesed notation)\n");
@@ -308,7 +393,8 @@ main(ac, av)
details=atoi(av[2]);
}
n=atoi(av[1]);
gen_tree(array, n, 0, 0);
gen_reduced_trees(n+1);
//gen_tree(array, n, 0, 0);
print_trees(details);
exit(0);
}