【问题标题】:constructing random "integer" tree - depth-first / breadth-first构建随机“整数”树 - 深度优先/广度优先
【发布时间】:2009-10-14 04:06:21
【问题描述】:

这是我第一次尝试用 c 编写递归函数。以下代码有效。我为长时间的发布道歉,但我试图尽可能清楚。

我正在尝试生成一个树,其中每个节点(inode)都有一个整数字段“n”。相应地,每个 inode 都有一个指向“n”个其他 inode 的指针数组。函数inode *I = gen_tree(inode *I, int nlevels); 生成一棵树,其中每个级别的inode 数量都是随机的。树以深度优先的方式生成。我有几个问题。

(a) 有没有更好的方法来编写函数?任何反馈/建议将不胜感激。

(b) 可以在 BF 时尚中生成树吗?

(c) I->i 应该有一个遍历树的索引。如何编写函数来计算I->i

(d)I->c 应该具有给定节点下所有 inode 的累积和。如何编写函数来计算I->c

提前致谢,

~拉斯

//.h file:
typedef struct integerNode {
  int n;
  int c;
  int i;
  struct integerNode **nodes;
} inode;
inode *new_inode( int n );
inode *gen_itree( inode *I, int nlevels );


//Constructor:
inode *new_inode( int n ){
    inode *I;
    I = malloc( sizeof (inode ) );
    I->n = n;
    I->nodes = malloc( n * sizeof (inode* ) );
    return (I );
};

//Generating tree with random-number of nodes:
inode *gen_itree( inode *I, int nlevels ){
    int i, next_level, next_n;
    printf( " \n" );
    printf( " I : %p\n", I );
    printf( " ***** nlevels : %d\n", nlevels );
    printf( " *************\n" );
    if ( nlevels == 0 ) {
        printf( " nlevels == 0!\n");
    } else {
        printf( " I->n : %d\n", I->n );
        printf( " *************\n" );
        next_level = nlevels - 1;
        for ( i = 0; i < I->n; i++ ) {
            printf( " I: %p\n",I);
            printf( " adding node number: %d\n", i );
            next_n = 0 + rand( ) % 3;
            I->nodes[i] = new_inode( next_n );
            printf( " I->nodes[%d]->n: %p, %d\n",i, I->nodes[i],next_n);
            I->nodes[i] = gen_itree( I->nodes[i], next_level );
        }
    }
    printf( " *************\n" );
    printf( " returning I : %p\n", I );//This part is unclear to me!
    printf( " *************\n" );
    return (I);
}

//Main.c
int main( int argc, char** argv ){
    inode *I;
    I = new_inode( 2 );
    I = gen_itree(I,3);
    return ( 1 );
}

【问题讨论】:

  • “遍历树的索引”是什么意思?
  • 这是理解遍历的实验的一部分。索引将简单地记录在 dfs/bfs 遍历中节点被访问的位置。我认为,下面的“计数器代码”应该可以帮助我编写该函数。拉斯

标签: c recursion tree tree-traversal


【解决方案1】:

首先。您没有错误检查。你只编写了你的​​快乐路径。 检查你的 malloc 不返回 NULL!!!

if (malloc returned NULL){
          free memory
          exit(error_code)
}

然后

 I->nodes[i] = new_inode( next_n );
 I->nodes[i] = gen_itree( I->nodes[i], next_level );

这部分不太清楚。你可以这样做

 I->nodes[i] = gen_itree( new_inode( next_n ), next_level );  

这里也一样

I = new_inode( 2 );
I = gen_itree(I,3);

可能是

 I = gen_itree(new_inode( 2 ),3);

另外,不要忘记释放分配的内存。

至于(d)

unsigned int get_node_count(inode* i){
    unsigned int counter =0;

    if (!i->nodes) return 0;

     //pseudocode
     for each inode* node in i->nodes{
        counter++
        counter+= get_node_count(node);//accumulate node count in child node
     }

      return counter;

【讨论】:

  • 谢谢。 (a) malloc 不检查以保持代码简单。 (b) I-&gt;nodes[i] = gen_itree( new_inode( next_n ), next_level ); 真的很有帮助。那是我缺乏理解。 (c) 计数器代码帮助我理解如何“结构化”遍历。
【解决方案2】:

一切看起来都不错。除非出于调试目的,否则我不会将 printf 放入函数中。

#define RANGE 3 // this eliminates 'magic constants'

//Generating tree with random-number of nodes:
inode *gen_itree( inode *I, int nlevels ){
        int i, next_level, next_n;

    if ( nlevels ) { // if nlevels != 0
        next_level = nlevels - 1;
        for ( i = 0; i < I->n; i++ ) {
            next_n = rand( ) % RANGE; // no need for a zero
            I->nodes[i] = new_inode( next_n );
            I->nodes[i] = gen_itree( I->nodes[i], next_level );
        }
    }

    return I;
}

这看起来更好,但我什至会更进一步,消除一些不必要的局部变量,因为它们只使用一次(除了 int i)。

对于 (c),这应该有效:

//This computes the C's for all nodes under this, including this node  
int computeAllCs( inode *I ){
        int i;
        I->c = 0;
        for ( i = 0; i < I->n; i++ )
            I->c += computeAllCs(I->nodes[i]) + 1;
}

请注意,“所有递归函数都可以迭代编写(也称为循环)”,因此您可能需要考虑迭代解决方案。

【讨论】:

    猜你喜欢
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多