2009-12-27 8 views
0

У меня есть функция get_trees(), которая работает на сложной древовидной структуре T и возвращает две структурные древовидные структуры A и B. Единственный способ, которым я смог заставить это работать заключается в создании новой структуры с с указателями на а и в, который затем передается в качестве параметра функции, а также является возвращаемое значение:Возвращение и использование нескольких древовидных структур в рекурсивной функции

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

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

Корневые узлы деревьев & B инициализируются в другой функции :

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() перемещается по ветвям дополнения T, выделяет и заполняет узлы A и B и рекурсивно вызывает себя в субодах. Упрощенный код:

//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]); 
    } 
} 

Код работает нормально. Однако это кажется очень уродливым.

(1) C не имеет внутреннего значения и, т. Е. Используется для возврата нескольких значений. Есть ли альтернатива? Что-то по следующим направлениям:

(2) Можно ли написать рекурсивную функцию со следующей подписью:

void get_trees(T, A, B); 

Is кажется, что если я прохожу корневые узлы А & В качестве параметров и подузлами выделяются внутри рекурсивной функции, тогда есть так называемая непрерывная цепочка команд, и все дерево должно быть доступно, когда завершается рекурсивный вызов. Это не сработало для меня, поэтому его нельзя допускать. Я был бы признателен, если бы кто-нибудь мог объяснить, почему это так, или если возможно более элегантное решение?

Спасибо и счастливые праздники. ~ RT

ответ

1

Все, что вы сделали, это единственный способ вернуть несколько значений указателя в качестве возвращаемого значения функции. Но это не считается хорошей формой.

Хорошей формой было бы объявить, что ваша функция имеет параметры, а также параметры и использует возвращаемое значение для указания успеха или сбоя. например,

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

Спасибо за мгновенный отклик. Очевидно, это выглядит намного чище. Я все еще не уверен, как бы я связал ** AOut с * A, на каждом рекурсивном шаге? Вы можете указать конкретное описание? Это прояснит кучу ошибочных предположений с моей стороны. спасибо, RT – user151410

+0

Хотел бы я помочь, но неясно, как вы сейчас используете композицию, поэтому я не знаю, как ее заменить. 'C = get_trees (T-> узлы [i], A-> узлы [p], B-> узлы [q]);' отсутствует аргумент arg, как вы возвращаете возвращаемое значение обратно в рекурсивную функцию? –

+0

Добавьте новый «ответ» для дополнительного места. RT – user151410

0

Передача указателя на композицию вызывающих может позволить функции использовать это для хранения результатов. Конечно, очень важно, чтобы создать составной объект первым, в стеке или куче ...

composite c; 
    get_trees(&c); 

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

конечно функция может фактически вернуться на структуру, которая будет скопирована к абоненту, но я хотел бы использовать только этот стиль ограниченные случаи ...

0

Это более простая версия вопроса. Предположим, у нас есть узел:

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

Теперь следующий код клонирует древовидную структуру с-значения данных в два раза (без проверки ошибок).

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; 
} 

Моя исходная задача включала в себя два варианта:

(а) Было несколько возвратных дерев (скажем double_tree, square_tree).

(b) Структура деревьев возврата отличается от дерева ввода.

Похоже, что основная проблема заключается в том, что «структура, назначенная внутри функции, должна быть« возвращена »как функция, выводимая как указатель», просто передача указателя в качестве параметра не делает трюк. Я надеюсь, что я ошибаюсь и что есть лучший способ сделать это.

Еще раз спасибо за помощь, Russ

Смежные вопросы