2009-12-27 5 views
0

J'ai une fonction get_trees() qui fonctionne sur une structure arborescente complexe T et retourne deux structures arborescentes de composants A et B. La seule façon dont j'ai pu faire fonctionner ceci est de créer une nouvelle structure C avec des pointeurs vers a et B, qui est ensuite transmis en tant que paramètre à la fonction et est également une valeur de retour:retourner et utiliser plusieurs structures arborescentes dans une fonction récursive

typedef struct Composite { 
itree *A; 
itree *B; 
} composite; 

composite *get_trees(complextree *T, itree *A, itree *B, composite *C); 

noeuds racines des arbres a & B sont initialisés dans une autre fonction :

itree *A = new_itree(0); 
itree *B = new_itree(0); 
A->n  = T->a; 
B->n  = T->b; 
composite *C; 
C = get_trees(T, A, B, C); 

ge t_trees() parcourt les branches de l'arbre complexe T, alloue et remplit les noeuds de A et B et s'appelle récursivement sur les sous-noeuds. Code simplifié:

//code for allocating subnodes of A and B  
if (T->nodes != NULL){ 
    for (i=0; i< T->nn; i++){ 
    //code for computing p & q 
    C = get_trees(T->nodes[i], A->nodes[p], B->nodes[q]); 
    } 
} 

Le code fonctionne correctement. Cependant, il semble très laid.

(1) C n'a pas de signification intrinsèque et est utilisé pour permettre le retour de plusieurs valeurs. Y a-t-il une alternative? Quelque chose de la manière suivante:

(2) Est-il possible d'écrire la fonction récursive avec la signature suivante:

void get_trees(T, A, B); 

Is semble que si je passe des noeuds de racine d'un & B en tant que paramètres et les sous-nœuds sont alloués dans la fonction récursive, alors il y a une chaîne continue de commande pour ainsi dire et l'arbre entier devrait être disponible quand l'appel récursif se termine. Cela n'a pas fonctionné pour moi, donc cela ne doit pas être autorisé. J'apprécierais que quelqu'un puisse expliquer pourquoi c'est le cas, ou si une solution plus élégante est possible ??

Merci et joyeuses fêtes. ~ RT

Répondre

1

Ce que vous avez fait est le seul moyen de renvoyer plusieurs valeurs de pointeur comme valeur de retour d'une fonction. Mais ce n'est pas considéré comme une bonne forme.

La bonne forme serait de déclarer que votre fonction possède des paramètres ainsi que des paramètres et d'utiliser la valeur de retour pour indiquer le succès ou l'échec. comme ceci

bool get_trees(complextree *T, itree *A, itree *B, composite *C, itree ** AOut, itree** BOut); 
+0

Merci pour la réponse instantanée. Cela semble évidemment beaucoup plus propre. Je ne suis toujours pas sûr, comment j'attacherais ** AOut avec * A, à chaque étape récursive? Pouvez-vous fournir une description concrète? Cela permettra de clarifier un tas d'hypothèses erronées de ma part. merci, RT – user151410

+0

Je voudrais pouvoir vous aider, mais il n'est pas clair comment vous utilisez le composite maintenant, donc je ne sais pas comment le remplacer. 'C = get_trees (T-> nœuds [i], A-> nœuds [p], B-> nœuds [q]);' manque un argument, comment réinjecter la valeur de retour dans la fonction récursive? –

+0

Ajouter une nouvelle "réponse" pour plus d'espace.RT – user151410

0

ouais passer un pointeur vers le composite des appelants laisserait la fonction utiliser cela pour stocker les résultats. Bien sûr, il est essentiel de créer l'objet composite en premier lieu, sur la pile ou tas ...

composite c; 
    get_trees(&c); 

    composite *c = malloc... 
    get_trees(c) 

bien sûr la fonction pourrait retourner en fait une struct qui sont copiés à l'appelant, mais je n'utiliseraient ce style dans cas limités ...

0

Voici une version plus simple de la question. Supposons que nous ayons un nœud:

typedef struct Node { 
    int n; // number of sub-nodes 
    int i; // data 
    node **nodes;//subnodes 
} node; 

maintenant le code suivant Clones la structure arborescente avec les données des valeurs doublées (sans aucune vérification d'erreur).

node *double_tree(node *A, node *B) { 
    if (B == NULL) { 
    B = (node*) calloc(1, sizeof (node)); 
    } 
    B->i = 2 * A->i; 
    B->n = A->n; 
    if (A->nodes != NULL) { 
    B->nodes = (node **) calloc(1, A->n * sizeof (node*)); 
    int ii; 
    for (ii = 0; ii < A->n; ii++) { 
     B->nodes[ii] = double_tree(A->nodes[ii], B->nodes[ii]); 
    } 
    } 
    return B; 
} 

Mon problème d'origine impliquait deux variantes:

(a) Il y avait plusieurs arbres de retour (par exemple double_tree, square_tree).(B) La structure des arbres de retour était différente de l'arbre d'entrée.

Il semble que le problème principal est que "une structure allouée à l'intérieur d'une fonction doit être" retournée "comme une sortie de fonction en tant que pointeur", juste passer le pointeur comme paramètre ne fait pas l'affaire. J'espère que j'ai tort et qu'il y a une meilleure façon de le faire.

Merci encore pour l'aide, Russ

Questions connexes