/* debugging function */ static void tree_debug(struct node_t *p) { if(p == NULL) { printf("NULL!!!!\n"); return; } if(p->op == O_NUM) { printf("number: %d\n",*(int *)p->left); } else if(p->op == O_ID) { printf("id: %s\n",(char *)p->left); } else { /* tree node */ tree_debug(p->left); printf("op : %d\n",p->op); tree_debug(p->right); } }
tree *makeBalancedTreeFromArray(int randseed, int *array, int array_size) { tree *t; treenode *n, *pnode; treenode **available; int i; char *side_attached; //Allocate list for nodes that have available links to attach children. available = (treenode**)malloc(sizeof(treenode*) * array_size); if(available == NULL) { perror(PROGNAME ": error: error allocating memory"); exit(1); } //Allocate tree. t = (tree*)malloc(sizeof(tree)); if(t == NULL) { perror(PROGNAME ": error: error allocating memory"); exit(1); } tree_init(t); t->node_count = array_size; //For randint function srand(randseed); for(i = 0; i < array_size; i++) { //Allocate new treenode n = (treenode*)malloc(sizeof(treenode)); if(n == NULL) { perror(PROGNAME ": error: error allocating memory"); exit(1); } //Initialize values of new treenode. treenode_init(n); n->id = i; n->data = (void*)&array[i]; //Add to available queue. If root node, set as head of tree. available[i] = n; if(i == 0) { t->head = n; continue; } //Root [Parent]:[Child] ... //0 1:0 2:0 3:1 4:1 5:2 6:2 7:3 8:3 9:4 10:4 //parent_id in balanced tree with root labeled 0 is (i-1)/2; pnode = available[(i-1)/2]; if(pnode == NULL) { printf(PROGNAME ": error: error in building balanced tree" " (parent node already full)\n"); exit(1); } tree_debug(2, "Parent chosen for node %d : %d\n", n->id, pnode->id); //Always select left first, if full then right. if(pnode->left == NULL) { pnode->left = n; side_attached = "left"; } else { pnode->right = n; side_attached = "right"; } //Check if both children are filled, and take off available list if so. if(pnode->left != NULL && pnode->right != NULL) { available[pnode->id] = NULL; } tree_debug(2, "Child node %d attached at parent node %d on %s\n", n->id, pnode->id, side_attached); } free(available); return t; }
tree *makeRandomTreeFromArray(int randseed, int *array, int array_size) { tree *t; treenode *n, *pnode; treenode **available; int i, r; char *side_attached; //Allocate list for nodes that have available links to attach children. available = (treenode**)malloc(sizeof(treenode*) * array_size); if(available == NULL) { perror(PROGNAME ": error: error allocating memory"); exit(1); } //Allocate tree. t = (tree*)malloc(sizeof(tree)); if(t == NULL) { perror(PROGNAME ": error: error allocating memory"); exit(1); } tree_init(t); t->node_count = array_size; //For randint function srand(randseed); for(i = 0; i < array_size; i++) { //Allocate new treenode n = (treenode*)malloc(sizeof(treenode)); if(n == NULL) { perror(PROGNAME ": error: error allocating memory"); exit(1); } //Initialize values of new treenode. treenode_init(n); n->id = i; n->data = (void*)&array[i]; //Add to available array. If root node, set as head of tree. available[i] = n; if(i == 0) { t->head = n; continue; } //Select parent randomly until found pnode = NULL; while(pnode == NULL) { pnode = available[randint(i)]; } tree_debug(2, "Parent chosen for node %d : %d\n", n->id, pnode->id); //Randomly select left or right child link to attach to. //Try other child if the selected link is not available. r = randint(2); if(r == 0) { if(pnode->left == NULL) { pnode->left = n; side_attached = "left"; } else { pnode->right = n; side_attached = "right"; } } else { if(pnode->right == NULL) { pnode->right = n; side_attached = "right"; } else { pnode->left = n; side_attached = "left"; } } //Check if both children are filled, and take off available list if so. if(pnode->left != NULL && pnode->right != NULL) { available[pnode->id] = NULL; } tree_debug(2, "Child node %d attached at parent node %d on %s\n", n->id, pnode->id, side_attached); } free(available); return t; }