Files
Le-Compte-est-Bon/tree.c

316 lines
7.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "lceb.h"
static TREE *trees=NULL;
static int ntrees=0;
static NODE *freenodes=NULL;
static int totnodes=0;
NODE *get_node()
{
NODE *ret;
if (!freenodes) {
register int i;
freenodes=malloc(ALLOCSIZE*sizeof(NODE));
totnodes+=ALLOCSIZE;
printf("allocating %d nodes - total nodes=%d\n", ALLOCSIZE, totnodes);
for (i=0; i<ALLOCSIZE-1; ++i) { /* create chained list */
(freenodes+i)->left=NULL;
(freenodes+i)->right=NULL;
(freenodes+i)->next=freenodes+i+1;
}
(freenodes+ALLOCSIZE-1)->next=NULL;
}
ret=freenodes;
freenodes=ret->next;
ret->op=Nop;
ret->val=-1;
ret->eval=-1;
ret->next=NULL;
ret->left=NULL;
ret->right=NULL;
return ret;
}
void free_node(node)
NODE *node;
{
if (node->left) {
free_node(node->left);
node->left=NULL;
}
if (node->right) {
free_node(node->right);
node->right=NULL;
}
node->next=freenodes;
freenodes=node;
}
void print_node(node, side, depth, details)
NODE *node;
char side;
int depth;
int details;
{
int i;
if (!node)
return;
switch (details) {
case 1:
if (node->type==TREE_NODE) {
printf("%c ", node->op);
} else {
printf("%d ", node->val);
}
print_node(node->left, TREE_LEFT, depth+1, details);
print_node(node->right, TREE_RIGHT, depth+1, details);
break;
case 0:
print_node(node->left, TREE_LEFT, depth+1, details);
print_node(node->right, TREE_RIGHT, depth+1, details);
if (node->type==TREE_NODE) {
printf("%c ", node->op);
} else {
printf("%d ", node->val);
}
break;
case 3:
if (node->type==TREE_NODE) {
if (!depth) {
printf("(%c", node->op);
//printf("(op");
} else {
//printf(" (op");
printf(" (%c", node->op);
}
} else {
printf(" %d", node->val);
}
print_node(node->left, TREE_LEFT, depth+1, details);
print_node(node->right, TREE_RIGHT, depth+1, details);
if (node->type==TREE_NODE) {
printf(")");
}
break;
case 4:
if (node->type==TREE_NODE) {
printf("(");
}
print_node(node->left, TREE_LEFT, depth+1, details);
if (node->type==TREE_NODE) {
printf(" %c ", node->op);
} else {
printf("%d", node->val);
}
print_node(node->right, TREE_RIGHT, depth+1, details);
if (node->type==TREE_NODE) {
printf(")");
}
break;
case 2:
/* left padding */
for (i=0; i<=depth; ++i)
printf(" ");
printf("%c: type:%s ", side, node->type==TREE_NODE? "node": "leaf");
if (details) {
printf("op=%c val=%d eval=%d", node->op, node->val, node->eval);
}
putchar('\n');
print_node(node->left, TREE_LEFT, depth+1, details);
print_node(node->right, TREE_RIGHT, depth+1, details);
break;;
}
}
void print_tree(tree, details)
TREE *tree;
int details;
{
int i;
switch (details) {
case 2:
print_node(tree->head, TREE_TOP, 0, details);
break;
case 0:
case 1:
case 3:
case 4:
//printf("Tree [%s] : ", tree->name);
print_node(tree->head, TREE_TOP, 0, details);
printf("\n");
break;
}
}
void print_trees(details)
int details;
{
TREE *tree=trees;
printf("There are %d trees:\n", ntrees);
while (tree) {
print_tree(tree, details);
tree=tree->next;
}
}
TREE *new_tree(name)
char *name;
{
TREE *tree;
tree=malloc(sizeof(TREE));
strcpy(tree->name, name);
tree->nodes=0;
tree->leaves=0;
tree->depth=0;
tree->head=NULL;
tree->next=trees;
trees=tree;
return tree;
}
NODE *dup_node(src)
NODE *src;
{
NODE *dst;
dst=get_node();
dst->type=src->type;
if (src->type==TREE_NODE) {
dst->op=src->op;
dst->left=dup_node(src->left);
dst->right=dup_node(src->right);
} else {
dst->val=src->val;
}
return dst;
}
/*void free_node(node)
NODE *node;
{
if (node->type==TREE_LEAF) {
node->next=freenodes;
freenodes=node;
} else {
free_node(node->left);
free_node(node->right);
node->next=freenodes;
freenodes=node;
}
}*/
NODE *build_tree(desc, size)
int *desc;
int size;
{
NODE *root, *node;
NODE *nodestack[1024]; /* TODO: make it dynamic */
int i, curnode=0;
root=get_node();
root->type=TREE_NODE;
nodestack[curnode++]=root;
for(i=1; i<size; ++i) {
node = get_node();
if (desc[i-1]) {
nodestack[curnode-1]->left = node;
} else {
nodestack[curnode-1]->right = node;
curnode--;
}
if (desc[i]) {
node->type=TREE_NODE;
nodestack[curnode++]=node;
} else {
node->type=TREE_LEAF;
}
}
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" */
{
int i;
char name[80];
TREE *tree;
if((nb1 + nb0) == 2*n) { /* end */
seq[2*n] = 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);
return;
}
if(nb1 >= nb0 && nb1 < n) {
seq[nb1+nb0] = 1;
gen_tree(seq, n, nb1+1, nb0);
}
if(nb0 < nb1 && nb1 <=n) {
seq[nb1+nb0] = 0;
gen_tree(seq, n, nb1, nb0+1);
}
}
TREE *nth_tree(n)
int n;
{
int i;
TREE *tree=trees;
for (i=0; i<n && tree; ++i) {
tree=tree->next;
}
return tree;
}
int n_trees()
{
return ntrees;
}
#ifdef STANDALONE
main(ac, av)
int ac;
char **av;
{
int n, details=0;
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");
exit (1);
}
if (ac==3) {
details=atoi(av[2]);
}
n=atoi(av[1]);
gen_tree(array, n, 0, 0);
print_trees(details);
exit(0);
}
#endif