int main() { TREE t1, t2, tree; srand((unsigned int) time(NULL)); int i; tree = tree_create(0, NULL, NULL); tree_print_list(tree); printf("\nTree depth : %d\n", tree_depth(tree)); printf("Tree is balanced : %d\n", tree_is_balanced(tree)); tree_add(tree, 1); tree_print_list(tree); printf("\nTree depth : %d\n", tree_depth(tree)); printf("Tree is balanced : %d\n", tree_is_balanced(tree)); tree_add(tree, 2); tree_print_list(tree); printf("\nTree depth : %d\n", tree_depth(tree)); printf("Tree is balanced : %d\n", tree_is_balanced(tree)); tree_add(tree, -2); tree_print_list(tree); printf("\nTree depth : %d\n", tree_depth(tree)); printf("Tree is balanced : %d\n", tree_is_balanced(tree)); tree_add(tree, -1); tree_print_list(tree); printf("\nTree depth : %d\n", tree_depth(tree)); printf("Tree is balanced : %d\n", tree_is_balanced(tree)); return 0; }
/** Insert entry into the index tree. * * Compares the value of the string with the value in the root node, then * either recursively inserts the value in the left or right sub-trees, or * adds the value to the root node. * * @param[in] root_node - a pointer to the root of the (sub-)tree. * @param[in] value_str_len - length of the string to be inserted. * @param[in] value_str - A pointer to string to be inserted. * @param[in] p - The "location" value associated with the string. * * @return New root node of the tree, or null if there is an error inserting * the string value (memory allocation failure) */ static IndexTreeNode *index_tree_insert( IndexTreeNode *root_node, size_t value_str_len, const char *value_str, void *p) { int cmp = compare_with_tree_node(value_str_len, value_str, root_node); if (cmp < 0) { /* Put it into the left-hand subtree */ if (root_node->left_node) { IndexTreeNode *new_subtree_root = index_tree_insert(root_node->left_node, value_str_len, value_str, p); if (!new_subtree_root) /* Error return */ return (IndexTreeNode *)0; root_node->left_node = new_subtree_root; root_node->left_depth = tree_depth(new_subtree_root); } else { IndexTreeNode *new_node = create_index_tree_node(root_node, value_str_len, value_str, p); if (!new_node) return (IndexTreeNode *)0; root_node->left_node = new_node; root_node->left_depth = 1; } } else if (cmp > 0) { /* Put it into the right-hand subtree */ if (root_node->right_node) { IndexTreeNode *new_subtree_root = index_tree_insert(root_node->right_node, value_str_len, value_str, p); if (!new_subtree_root) /* Error return */ return (IndexTreeNode *)0; root_node->right_node = new_subtree_root; root_node->right_depth = tree_depth(new_subtree_root); } else { IndexTreeNode *new_node = create_index_tree_node(root_node, value_str_len, value_str, p); if (!new_node) return (IndexTreeNode *)0; root_node->right_node = new_node; root_node->right_depth = 1; } } else { /* Add it to the current node */ if (!index_node_insert_value(root_node, p)) return (IndexTreeNode *)0; } /* Perform any re-balancing required */ return rebalance_tree(root_node); }
/* Return tree height. XXX this is not tail-recursive! */ static int tree_depth (Dict_node *n) { int l, r; if (NULL == n) return 0; if (NULL == n->left) return 1+tree_depth(n->right); if (NULL == n->right) return 1+tree_depth(n->left); l = tree_depth(n->left); r = tree_depth(n->right); if (l < r) return r+1; return l+1; }
int tree_depth(BiTree *T){ if(T != NULL){ int ldepth,rdepth; ldepth = tree_depth(T->lchild); rdepth = tree_depth(T->rchild); return ldepth > rdepth ? (ldepth+1) : (rdepth+1); }else{ return 0; } }
/** Extract the rightmost entry of the given sub-tree. * * First locate the rightmost entry. If this is the root node, then the new * root node is the node's left sub-tree. Otherwise, the parent's right node * becomes the rightmost node's left sub-tree, and we traverse the tree to the * root node, rebalancing as we go. * * @param[in] root_node - a pointer to the root of the (sub-)tree. * @param[in] rightmost_node - pointer to the location to store the rightmost node's pointer. * * @return New root node of the (sub-)tree, or null if the tree is now empty */ static IndexTreeNode *extract_rightmost(IndexTreeNode *root_node, IndexTreeNode **rightmost_node) { IndexTreeNode *parent_node, *current_node; *rightmost_node = root_node; while ((*rightmost_node)->right_node) { *rightmost_node = (*rightmost_node)->right_node; } /* Remove the rightmost node from the tree */ if (*rightmost_node == root_node) { /* Just return the left sub-tree - already balanced, or empty */ return (*rightmost_node)->left_node; } else { /* Move the rightmost node's left sub-tree to the parent's right sub-tree */ current_node = (*rightmost_node)->parent_node; current_node->right_node = (*rightmost_node)->left_node; if (current_node->right_node) current_node->right_node->parent_node = current_node; current_node->right_depth = tree_depth(current_node->right_node); } while (current_node != root_node) { parent_node = current_node->parent_node; parent_node->right_node = rebalance_tree(current_node); current_node = parent_node; } return rebalance_tree(current_node); }
int main(int argc, char **argv) { /* 根据前序和中序遍历结果构造二叉树 */ unsigned char pre_seq[] = { 4, 2, 1, 3, 6, 5, 7 }; unsigned char in_seq[] = { 1, 2, 3, 4, 5, 6, 7 }; /* * 4 * / \ * 2 6 * / \ / \ * 1 3 5 7 */ printf("Create a tree with pre and in sequence\n"); BiTree bTree = init(pre_seq, in_seq, 7); printf("Fork a tree\n"); BiTree forkTree; forkTree = fork_tree(bTree); printf("pre: "); pre_order(forkTree, print_item); putchar('\n'); printf("Tree count = %d depth = %d\n", tree_leavess(forkTree), tree_depth(forkTree)); tree_destroy(bTree); tree_destroy(forkTree); return 0; }
int individual_depth ( individual *ind ) { int i, j, k = 0; for ( j = 0; j < tree_count; ++j ) { if ( ( i = tree_depth ( ind->tr[j].data ) ) > k ) k = i; } return k; }
int main(void){ BiTree *T = NULL; create_bitree(&T); //traverse(T, 0); int d = tree_depth(T); printf("depth:%d\n", d); return 0; }
// number of nodes on the longest path int tree_depth( SearchTree T ) { // returns -1 if T is NULL if (T == NULL) { return -1; } else { int leftD, rightD; leftD = tree_depth (T -> left); rightD = tree_depth (T -> right); // select the larger if (leftD > rightD) { return (leftD + 1); } else { return (rightD + 1); } } }
void print_tree(IndexTreeNode *root_node, unsigned depth) { char *value_str; int i; char buffer[256]; if (!root_node) return; print_tree(root_node->left_node, depth+1); for (i = 0; i < depth; i++) SLPDLog(" "); value_str = get_value_string(root_node); sprintf(buffer, "%03d %3d %s\n", tree_depth(root_node), count_values(root_node), value_str); SLPDLog(buffer); free(value_str); print_tree(root_node->right_node, depth+1); }
/** Calculates the greatest depth of the tree. @param t tree to find the depth of. @return maximum depth of the tree. */ int tree_depth(tree t) { if(t->left != NULL && t->right != NULL){ return tree_depth(t->left) > tree_depth(t->right) ? tree_depth(t->left)+1 : tree_depth(t->right)+1; }else if(t->left != NULL){ return tree_depth(t->left)+1; }else if(t->right != NULL){ return tree_depth(t->right)+1; }else{ return 0; } }
int main (int argc, char *argv[]){ FILE *f = NULL; Tree *tree = NULL; EleTree *pele = NULL; Cadena* cad = NULL; int numnodos, profundidad; char cadena[MAX], buscar[MAX]; if(argc != 2){ /*Comprobamos argumentos*/ printf("Faltan argumentos\n"); return -1; } f = fopen (argv[1], "r"); /*Abrimos el fichero recibido como argumento*/ if (!f){ return -1; } tree = tree_ini(); /*Inicializamos el árbol en el que vamos a guardar las cadenas*/ if (!tree){ fclose(f); return -1; } while (feof(f) == 0){ /*Bucle que lee uno a uno las cadenas del fichero*/ fscanf (f, "%s\n", cadena); /*Guardamos el dato leido en cadena*/ pele = eletree_ini(); /*Inicializamos un EleTree*/ if (!pele){ fclose(f); tree_free(tree); return -1; } cad = cadena_ini(); /*Inicializamos una cadena*/ if(!cad){ eletree_free(pele); fclose(f); tree_free(tree); return -1; } if(!cadena_setInfo(cad, cadena)){ fclose(f); tree_free(tree); eletree_free(pele); cadena_free(cad); return -1; } if (!eletree_setInfo (pele, cad)){ /*Asignamos al EleTree la cadena guardada*/ fclose(f); tree_free(tree); eletree_free(pele); cadena_free(cad); return -1; } tree_insert (tree, pele); /*Insertamos el EleTree en el árbol*/ eletree_free(pele); cadena_free(cad); } numnodos = tree_numNodes (tree); profundidad = tree_depth (tree); printf ("Número de nodos: %d\n", numnodos); printf ("Profundidad: %d\n", profundidad); if(tree_inOrder(stdout, tree) == ERROR){ fclose (f); tree_free(tree); return -1; } printf ("Introduce una cadena para buscar en el árbol (siguiendo el mismo formato que en el fichero de entrada): "); scanf ("%s", buscar); pele = eletree_ini(); /*Inicializamos un EleTree*/ if (!pele){ fclose (f); tree_free(tree); return -1; } cad = cadena_ini(); /*Inicializamos una cadena*/ if(!cad){ fclose (f); tree_free(tree); eletree_free(pele); return -1; } if(!cadena_setInfo(cad, buscar)){ fclose(f); tree_free(tree); eletree_free(pele); cadena_free(cad); return -1; } if (!eletree_setInfo(pele, cad)){ /*Asignamos al EleTree la cadena "buscar"*/ fclose (f); tree_free(tree); eletree_free(pele); return -1; } if (tree_findEleTree (tree, pele) == TRUE){ /*Buscamos en el árbol el entero introducido previamente*/ printf ("El dato %s se encuentra dentro del árbol\n", buscar); } else { printf ("El dato %s NO se encuentra dentro del árbol\n", buscar); } tree_free(tree); /*Liberamos toda la memoria*/ eletree_free(pele); fclose (f); cadena_free(cad); return -1; }
/** Delete entry from the index tree. * * Compares the value of the string with the value in the root node, then * either recursively deletes the value in the left or right sub-trees, or * deletes the value from the root node. * If the root_node needs to be deleted, then create a new tree from its * subtrees, re-balancing where necessary. * * @param[in] root_node - a pointer to the root of the (sub-)tree. * @param[in] value_str_len - length of the string to be removed. * @param[in] value_str - A pointer to string to be removed. * @param[in] p - The "location" value associated with the string. * * @return New root node of the tree, or null if the tree is now empty */ IndexTreeNode *index_tree_delete( IndexTreeNode *root_node, size_t value_str_len, const char *value_str, void *p) { int cmp; if (!root_node) /* Shouldn't really happen, but nothing to do */ return root_node; cmp = compare_with_tree_node(value_str_len, value_str, root_node); if (cmp < 0) { root_node->left_node = index_tree_delete(root_node->left_node, value_str_len, value_str, p); root_node->left_depth = tree_depth(root_node->left_node); if (root_node->left_node) root_node->left_node->parent_node = root_node; } else if (cmp > 0) { root_node->right_node = index_tree_delete(root_node->right_node, value_str_len, value_str, p); root_node->right_depth = tree_depth(root_node->right_node); if (root_node->right_node) root_node->right_node->parent_node = root_node; } else { IndexTreeNode *replacement_node; /* Find the given location in the value list */ IndexTreeValue *entry = find_in_value_set(root_node->value, p); if (!entry) /* Shouldn't really happen, but nothing to do */ return root_node; root_node->value = remove_from_value_set(root_node->value, entry); free_index_tree_value(entry); if (root_node->value) /* All we've done is remove one of the values in the set for this node, * so the tree structure does not need to be changed */ return root_node; /* The node needs to be deleted, so replace this node by the leftmost * node of the right sub-tree, or the rightmost mode of the left * sub-tree, depending on which has the greater depth */ if (root_node->left_depth > root_node->right_depth) { root_node->left_node = extract_rightmost(root_node->left_node, &replacement_node); root_node->left_depth = tree_depth(root_node->left_node); } else if (root_node->right_node) { root_node->right_node = extract_leftmost(root_node->right_node, &replacement_node); root_node->right_depth = tree_depth(root_node->right_node); } else { /* Both sub-trees are empty ie. this is a leaf node */ free_index_tree_node(root_node); return (IndexTreeNode *)0; } replacement_node->right_node = root_node->right_node; replacement_node->right_depth = root_node->right_depth; if (replacement_node->right_node) replacement_node->right_node->parent_node = replacement_node; replacement_node->left_node = root_node->left_node; replacement_node->left_depth = root_node->left_depth; if (replacement_node->left_node) replacement_node->left_node->parent_node = replacement_node; free_index_tree_node(root_node); root_node = replacement_node; } root_node = rebalance_tree(root_node); #if defined(DEBUG) && defined(CHECKING) if (!check_tree(root_node)) { SLPDLog("Index tree check fails deleting from tree %p\n", root_node); } #endif return root_node; }
/** Re-balance the (sub-)tree, if necessary. * * Checks whether the tree is balanced, and performs rotations as required to * re-balance if necessary. * * @param[in] root_node - a pointer to the root of the (sub-)tree. * * @return New root node of the tree */ static IndexTreeNode *rebalance_tree( IndexTreeNode *root_node) { /* Check whether we need to re-balance the (sub-)tree */ if (root_node->left_depth - root_node->right_depth == 2) { /* Need to perform a right-rotation */ IndexTreeNode *parent_node; IndexTreeNode *pivot = root_node->left_node; if (tree_depth(pivot->right_node) > tree_depth(pivot->left_node)) { /* Rotate the pivot tree left first, as the right subtree will be * going beneath the current root node which will be going beneath * the pivot node, so will increase the depth. By rotating the * subtrees, we ensure that the shallower sub-tree has its depth * increased, to minimise the difference in depth */ IndexTreeNode *new_pivot = pivot->right_node; parent_node = pivot->parent_node; pivot->right_node = new_pivot->left_node; if (pivot->right_node) pivot->right_node->parent_node = pivot; pivot->right_depth = new_pivot->left_depth; pivot->parent_node = new_pivot; new_pivot->left_node = pivot; new_pivot->left_depth = tree_depth(pivot); new_pivot->parent_node = parent_node; pivot = new_pivot; } /* Now perform the right rotation */ parent_node = root_node->parent_node; root_node->left_node = pivot->right_node; if (root_node->left_node) root_node->left_node->parent_node = root_node; root_node->left_depth = pivot->right_depth; root_node->parent_node = pivot; pivot->right_node = root_node; pivot->right_depth = tree_depth(root_node); pivot->parent_node = parent_node; root_node = pivot; } else if (root_node->right_depth - root_node->left_depth == 2) { /* Need to perform a left-rotation */ IndexTreeNode *parent_node; IndexTreeNode *pivot = root_node->right_node; if (tree_depth(pivot->left_node) > tree_depth(pivot->right_node)) { /* Rotate the pivot tree right first, as the left subtree will be * going beneath the current root node which will be going beneath * the pivot node, so will increase the depth. By rotating the * subtrees, we ensure that the shallower sub-tree has its depth * increased, to minimise the difference in depth */ IndexTreeNode *new_pivot = pivot->left_node; parent_node = pivot->parent_node; pivot->left_node = new_pivot->right_node; if (pivot->left_node) pivot->left_node->parent_node = pivot; pivot->left_depth = new_pivot->right_depth; pivot->parent_node = new_pivot; new_pivot->right_node = pivot; new_pivot->right_depth = tree_depth(pivot); new_pivot->parent_node = parent_node; pivot = new_pivot; } /* Now perform the left rotation */ parent_node = root_node->parent_node; root_node->right_node = pivot->left_node; if (root_node->right_node) root_node->right_node->parent_node = root_node; root_node->right_depth = pivot->left_depth; root_node->parent_node = pivot; pivot->left_node = root_node; pivot->left_depth = tree_depth(root_node); pivot->parent_node = parent_node; root_node = pivot; } #if defined(DEBUG) && defined(CHECKING) if (!check_tree(root_node)) { SLPDLog("Index tree check fails after rebalancing tree %p\n", root_node); } #endif return root_node; }
void operator_crossover ( population *oldpop, population *newpop, void *data ) { crossover_data * cd; int p1, p2; int ps1, ps2; int l1, l2; lnode *st[3]; int sts1, sts2; int ns1, ns2; int badtree1, badtree2; double total; int forceany1, forceany2; int repcount; int f, t1, t2, j; double r, r2; int totalnodes1, totalnodes2; int i; /* get the crossover-specific data structure. */ cd = (crossover_data *)data; total = cd->internal + cd->external; /* choose a function set. */ r = random_double() * cd->treetotal; for ( f = 0; r >= cd->func[f]; ++f ); /* fill in the "treecumul" array, zeroing all trees which don't use the selected function set. */ r = 0.0; t1 = 0; for ( j = 0; j < tree_count; ++j ) { if ( tree_map[j].fset == f ) r = (cd->treecumul[j] = r + cd->tree[j]); else cd->treecumul[j] = r; } /* select the first and second trees. */ r2 = random_double() * r; for ( t1 = 0; r2 >= cd->treecumul[t1]; ++t1 ); r2 = random_double() * r; for ( t2 = 0; r2 >= cd->treecumul[t2]; ++t2 ); #ifdef DEBUG_CROSSOVER printf ( "selected function set %d --> t1: %d; t2: %d\n", f, t1, t2 ); #endif /* choose two parents */ p1 = cd->sc->select_method ( cd->sc ); ps1 = oldpop->ind[p1].tr[t1].nodes; /* if the tree only has one node, we obviously can't do fucntionpoint crossover. use anypoint instead. */ forceany1 = (ps1==1||total==0.0); p2 = cd->sc2->select_method ( cd->sc2 ); ps2 = oldpop->ind[p2].tr[t2].nodes; forceany2 = (ps2==1||total==0.0); #ifdef DEBUG_CROSSOVER fprintf ( stderr, "parent 1 is:\n" ); print_individual ( oldpop->ind+p1, stderr ); fprintf ( stderr, "parent 2 is:\n" ); print_individual ( oldpop->ind+p2, stderr ); #endif while(1) { /* choose two crossover points */ if ( forceany1 ) { /* choose any point. */ l1 = random_int ( ps1 ); st[1] = get_subtree ( oldpop->ind[p1].tr[t1].data, l1 ); } else if ( total*random_double() < cd->internal ) { /* choose an internal point. */ l1 = random_int ( tree_nodes_internal (oldpop->ind[p1].tr[t1].data) ); st[1] = get_subtree_internal ( oldpop->ind[p1].tr[t1].data, l1 ); } else { /* choose an external point. */ l1 = random_int ( tree_nodes_external (oldpop->ind[p1].tr[t1].data) ); st[1] = get_subtree_external ( oldpop->ind[p1].tr[t1].data, l1 ); } if ( forceany2 ) { /* choose any point on second parent. */ l2 = random_int ( ps2 ); st[2] = get_subtree ( oldpop->ind[p2].tr[t2].data, l2 ); } else if ( total*random_double() < cd->internal ) { /* choose internal point. */ l2 = random_int ( tree_nodes_internal (oldpop->ind[p2].tr[t2].data) ); st[2] = get_subtree_internal ( oldpop->ind[p2].tr[t2].data, l2 ); } else { /* choose external point. */ l2 = random_int ( tree_nodes_external (oldpop->ind[p2].tr[t2].data) ); st[2] = get_subtree_external ( oldpop->ind[p2].tr[t2].data, l2 ); } #ifdef DEBUG_CROSSOVER printf ( "subtree 1 is: " ); print_tree ( st[1], stdout ); printf ( "subtree 2 is: " ); print_tree ( st[2], stdout ); #endif /* count the nodes in the selected subtrees. */ sts1 = tree_nodes ( st[1] ); sts2 = tree_nodes ( st[2] ); /* calculate the sizes of the offspring. */ ns1 = ps1 - sts1 + sts2; ns2 = ps2 - sts2 + sts1; totalnodes1 = ns1; totalnodes2 = ns2; #ifdef DEBUG_CROSSOVER printf ( "newtree 1 has size %d; limit is %d\n", ns1, tree_map[t1].nodelimit ); #endif /** validate the first offspring against the tree node and depth limits; set "badtree1" if any are violated. **/ badtree1 = 0; if ( tree_map[t1].nodelimit > -1 && ns1 > tree_map[t1].nodelimit ) badtree1 = 1; else if ( tree_map[t1].depthlimit > -1 ) { ns1 = tree_depth_to_subtree ( oldpop->ind[p1].tr[t1].data, st[1] ) + tree_depth ( st[2] ); #ifdef DEBUG_CROSSOVER printf ( "newtree 1 has depth %d; limit is %d\n", ns1, tree_map[t1].depthlimit ); #endif if ( ns1 > tree_map[t1].depthlimit ) badtree1 = 1; } /* if we're supposed to keep trying, skip up and choose new crossover points. */ if ( cd->keep_trying && badtree1 ) continue; /** validate the second offspring against the tree node and depth limits; set "badtree2" if any are violated. **/ badtree2 = 0; if ( tree_map[t2].nodelimit > -1 && ns2 > tree_map[t2].nodelimit ) badtree2 = 1; else if ( tree_map[t2].depthlimit > -1 ) { ns2 = tree_depth_to_subtree ( oldpop->ind[p2].tr[t2].data, st[2] ) + tree_depth ( st[1] ); if ( ns2 > tree_map[t2].depthlimit ) badtree2 = 1; } /* if we're supposed to keep trying, skip up and choose new crossover points. */ if ( cd->keep_trying && badtree2 ) continue; /* check both offspring against the individual node limits, set badtree1 and/or badtree2 if either is too big. */ if ( ind_nodelimit > -1 ) { for ( i = 0; i < tree_count; ++i ) { if ( i != t1 ) totalnodes1 += oldpop->ind[p1].tr[i].nodes; if ( i != t2 ) totalnodes2 += oldpop->ind[p2].tr[i].nodes; } badtree1 |= (totalnodes1 > ind_nodelimit); badtree2 |= (totalnodes2 > ind_nodelimit); #ifdef DEBUG_CROSSOVER printf ( "newind 1 has %d nodes; limit is %d\n", totalnodes1, ind_nodelimit ); #endif } /* choose new crossover points if either tree is too big. */ if ( cd->keep_trying && (badtree1 || badtree2) ) continue; /* copy the first parent to the first offspring position */ duplicate_individual ( newpop->ind+newpop->next, oldpop->ind+p1 ); if ( !badtree1 ) { /* if the first offspring is allowable... */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 1 is allowable.\n" ); #endif /* make a copy of the crossover tree, replacing the selected subtree with the crossed-over subtree. */ copy_tree_replace_many ( 0, oldpop->ind[p1].tr[t1].data, st+1, st+2, 1, &repcount ); if ( repcount != 1 ) { /* this can't happen, but check anyway. */ error ( E_FATAL_ERROR, "botched crossover: this can't happen" ); } /* free the appropriate tree of the new individual */ free_tree ( newpop->ind[newpop->next].tr+t1 ); /* copy the crossovered tree to the freed space */ gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t1 ); /* the new individual's fitness fields are of course invalid. */ newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID; newpop->ind[newpop->next].flags = FLAG_NONE; } else { /* offspring too big but keep_trying not set, just leave the copied parent 1 in the offspring position. */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 1 is too big; copying parent 1.\n" ); #endif } /* we've just filled in one member of the new population. */ ++newpop->next; #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 1:" ); if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID ) fprintf ( stderr, " (valid)\n" ); else fprintf ( stderr, " (invalid)\n" ); print_individual ( newpop->ind+(newpop->next-1), stderr ); #endif /* if the new population needs another member (it's not full) */ if ( newpop->next < newpop->size ) { /* copy the second parent to the second offspring position. */ duplicate_individual ( newpop->ind+newpop->next, oldpop->ind+p2 ); if ( !badtree2 ) { /* if the second offspring is allowable... */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 2 is allowable.\n" ); #endif /* then make a copy of the tree, replacing the crossover subtree. */ copy_tree_replace_many ( 0, oldpop->ind[p2].tr[t2].data, st+2, st+1, 1, &repcount ); if ( repcount != 1 ) { error ( E_FATAL_ERROR, "bad crossover: this can't happen" ); } /* free the old tree in the new individual, and replace it with the crossover tree. */ free_tree ( newpop->ind[newpop->next].tr+t2 ); gensp_dup_tree ( 0, newpop->ind[newpop->next].tr+t2 ); newpop->ind[newpop->next].evald = EVAL_CACHE_INVALID; newpop->ind[newpop->next].flags = FLAG_NONE; } else { /* offspring too big but keep_trying not set; just leave the copy of parent 2 where it is. */ #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 2 is big; copying parent 2.\n" ); #endif } ++newpop->next; #ifdef DEBUG_CROSSOVER fprintf ( stderr, "offspring 2:" ); if ( newpop->ind[newpop->next-1].evald == EVAL_CACHE_VALID ) fprintf ( stderr, " (valid)\n" ); else fprintf ( stderr, " (invalid)\n" ); print_individual ( newpop->ind+(newpop->next-1), stderr ); #endif } #ifdef DEBUG_CROSSOVER else { /* the first offspring filled the population, discard the second. */ fprintf ( stderr, "offspring 2 not needed.\n\n" ); } #endif break; } #ifdef DEBUG_CROSSOVER printf ( "CROSSOVER COMPLETE.\n\n\n" ); #endif }
static int tree_balance(Dict_node *n) { int l = tree_depth(n->left); int r = tree_depth(n->right); return r-l; }
/** * Gathers input from the command line and responds to the given * arguments. * Refer to help menu (-h) for more information. * * @param argc count the number of arguments on the command line. * @param argv[] array of arguments. * * @return exit success or exit failure. */ int main (int argc, char *argv[]){ char word[256]; const char *optstring = "c:df:orh"; char option; tree h; tree_t tree_type = BST; FILE *outfile; char* out = NULL; FILE *filename; int unknown = 0; clock_t fill_start,fill_end, search_start, search_end; int cflag = 0; int dflag = 0; int oflag = 0; while ((option = getopt(argc,argv,optstring)) != EOF){ switch(option){ case'f': out = optarg; break; case 'o': oflag = 1; break; case 'r': tree_type = RBT; break; case 'd': dflag = 1; break; case 'c': if (NULL == (filename = fopen(optarg, "r"))) { fprintf(stderr, "%s: can't find file %s\n", argv[0], argv[1]); return EXIT_FAILURE; } cflag = 1; break; case 'h': print_usage(argv[0]); exit(EXIT_FAILURE); break; default: print_usage(argv[0]); exit(EXIT_FAILURE); } } if (out == NULL){ out = "tree-view.dot"; } h = tree_new(tree_type); fill_start = clock(); while (getword(word, sizeof word, stdin) != EOF){ h = tree_insert(h,word); } fill_end = clock(); if (oflag == 1){ outfile = fopen(out, "w"); tree_output_dot(h, outfile); fprintf(stderr,"Creating dot file '%s'\n",out ); fclose(outfile); } if (cflag == 1){ dflag = 0; oflag = 0; search_start = clock(); while (getword(word, sizeof word, filename) != EOF){ if (tree_search(h, word) == 0){ printf("%s\n", word); unknown++; } } search_end = clock(); fclose(filename); fprintf(stderr, "Fill time : %7f\nSearch time : %7f\nUnknown words = %d\n", \ (fill_end-fill_start)/(double)CLOCKS_PER_SEC, \ (search_end-search_start)/(double)CLOCKS_PER_SEC, unknown); } if (dflag == 1){ printf("%d\n",tree_depth(h)); }else if (dflag == 0 && cflag == 0 && oflag == 0){ tree_preorder(h, print_info); } tree_free(h); return EXIT_SUCCESS; }
static int test_lists(int num_items) { struct refltemp *check; RefList *list; int i; signed int h, k, l; Reflection *refl; RefListIterator *iter; check = malloc(num_items * sizeof(struct refltemp)); list = reflist_new(); h = RANDOM_INDEX; k = RANDOM_INDEX; l = RANDOM_INDEX; for ( i=0; i<num_items; i++ ) { int j; int num; if ( random() > RAND_MAX/2 ) { h = RANDOM_INDEX; k = RANDOM_INDEX; l = RANDOM_INDEX; } /* else use the same as last time */ /* Count the number of times this reflection appeared before */ num = 1; for ( j=0; j<i; j++ ) { if ( (check[j].h == h) && (check[j].k == k) && (check[j].l == l) ) { num++; } } /* Update all copies with this number */ for ( j=0; j<i; j++ ) { if ( (check[j].h == h) && (check[j].k == k) && (check[j].l == l) ) { check[j].num = num; } } add_refl(list, h, k, l); check[i].h = h; check[i].k = k; check[i].l = l; check[i].num = num; check[i].found = 0; } printf("Created %i items, num_reflections is %i, tree depth is %i\n", num_items, num_reflections(list), tree_depth(list)); /* Iterate over the list and check we find everything */ int count = 0; for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { signed int h, k, l; get_indices(refl, &h, &k, &l); for ( i=0; i<num_items; i++ ) { if ( (check[i].h == h) && (check[i].k == k) && (check[i].l == l) && (check[i].found == 0) ) { check[i].found = 1; break; } } count++; } if ( count != num_reflections(list) ) { fprintf(stderr, "num_reflections gave %i, iteration gave %i\n", num_reflections(list), count); return 1; } for ( i=0; i<num_items; i++ ) { if ( check[i].found == 0 ) { Reflection *test; fprintf(stderr, "Iteration didn't find %3i %3i %3i %i\n", check[i].h, check[i].k, check[i].l, i); test = find_refl(list, check[i].h, check[i].k, check[i].l); if ( test == NULL ) { fprintf(stderr, "Not in list\n"); } else { fprintf(stderr, "But found in list.\n"); } return 1; } } /* Check that all the reflections can be found */ for ( i=0; i<num_items; i++ ) { signed int h, k, l; Reflection *refl; h = check[i].h; k = check[i].k; l = check[i].l; refl = find_refl(list, h, k, l); if ( refl == NULL ) { fprintf(stderr, "Couldn't find %3i %3i %3i\n", h, k, l); return 1; } } reflist_free(list); free(check); return 0; }