0

我有一个函数 get_trees() 对复杂的树结构 T 进行操作并返回两个组件树结构 A 和 B。我能够让它工作的唯一方法是创建一个带有指向 A 和 B 的指针的新结构 C , 然后作为参数传递给函数,也是返回值:

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

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

树 A 和 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);

get_trees() 遍历 complextree 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);

似乎如果我将 A 和 B 的根节点作为参数传递,并且在递归函数中分配子节点,那么可以说有一个连续的命令链,当递归调用完成时,整个树应该可用。它对我不起作用,所以绝对不允许。如果有人能解释为什么会这样,或者是否有可能有更优雅的解决方案,我将不胜感激?

谢谢,节日快乐。~RT

4

3 回答 3

1

您所做的是将多个指针值作为函数的返回值返回的唯一方法。但它不被认为是好的形式。

好的形式是声明您的函数具有 out 参数以及 in 参数,并使用返回值来指示成功或失败。像这样

bool get_trees(complextree *T, itree *A, itree *B, composite *C, itree ** AOut, itree** BOut); 
于 2009-12-27T01:10:15.260 回答
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;
}

我最初的问题涉及两种变体:

(a) 有多个返回树(例如 double_tree、square_tree)。

(b) 返回树的结构与输入树不同。

似乎核心问题是“在函数内部分配的结构必须作为函数输出作为指针'返回'”,只是将指针作为参数传递并不能解决问题。我希望我错了,并且有更好的方法来做到这一点。

再次感谢您的帮助,拉斯

于 2009-12-27T14:39:11.363 回答
0

是的,将指针传递给调用者组合将使函数使用它来存储结果。当然,首先在堆栈或堆上创建复合对象至关重要......

   composite c;
   get_trees(&c);

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

当然,该函数实际上可以返回一个结构,该结构将被复制给调用者,但我只会在有限的情况下使用这种风格......

于 2009-12-27T01:12:23.527 回答