2015-11-17 116 views
-1

我能打印我的链接列表清单:打印链接使用递归函数

| 
|-> [ID: 3] Poetry 
| | 
| |-> [ID: 3] Notes 3 
| | 
| |-> [ID: 2] Notes 2 
| | 
| |-> [ID: 1] Notes 1 
| | 
| 
|-> [ID: 2] Diet 
| | 
| |-> [ID: 2] Diet 2 
| | 
| |-> [ID: 1] Diet 1 
| | 
| 
|-> [ID: 1] Program 

用下面的函数,我写道:

void printn(NODE *handle) //only 2 depths allowed 
    { 
    NODE *copy_handle = NULL; 
    NODE *depth1 = NULL; 
    NODE *depth2 = NULL; 

    for(copy_handle = handle ; copy_handle != NULL ; copy_handle = copy_handle->pNext ) 
     { 
     printf("|\n|-> [ID: %d] %s\n", copy_handle->id, copy_handle->pLabel); 

     if(copy_handle->pInner != NULL) 
      { 
      printf("|\t|\n"); 
      for(depth1 = copy_handle->pInner ; depth1 != NULL ; depth1 = depth1->pNext ) 
       { 
       printf("|\t|-> [ID: %d] %s\n", depth1->id, depth1->pLabel); 

       if(depth1->pInner != NULL) 
        { 
        printf("|\t|\t|\n"); 
        for(depth2 = depth1->pInner ; depth2 != NULL ; depth2 = depth2->pNext ) 
         { 
         printf("|\t|\t|-> [ID: %d] %s\n", depth2->id, depth2->pLabel); 
         } 
        } 

       printf("|\t|\t\n"); 
       } 
      } 
     } 

    } 

此功能但是在我有限的” m只能够打印节点的子节点和该子节点的子节点,或者在我的代码中调用它时,我只能打印深度= 2。我想要做的是能够打印无限的深度,所以我看着我的原始功能,我觉得重新设计它与递归将是适当的。所以,我制定了以下:

void rec_printn(NODE *handle, int tab) //unlimited depths 
    { 

    printf("tab %d\n", tab); //for testing purposes 
    NODE *copy_handle = handle; 
    for(; copy_handle != NULL ; copy_handle = copy_handle->pNext) 
     { 
     printf("%*s|-> [ID: %d] %s\n", tab, " ", copy_handle->id, copy_handle->pLabel); //add variable spacing 

     if(copy_handle->pInner != NULL) 
      { 
      tab+=5; 
      rec_printn(copy_handle->pInner , tab); 
      } 
     else if(copy_handle->pNext == NULL) 
      { 
      tab-=5; 
      printf("<take back the indent\n"); //for testing purposes 
      } 

     } 
    } 

我在这里要说的是缩进不回来,因为我希望他们在我的上面原来的例子,而是我得到了以下的麻烦:

tab 5 
    |-> [ID: 3] Poetry 
tab 10 
      |-> [ID: 3] Notes 3 
      |-> [ID: 2] Notes 2 
      |-> [ID: 1] Notes 1 
<take back the indent 
      |-> [ID: 2] Diet 
tab 15 
       |-> [ID: 2] Diet 2 
       |-> [ID: 1] Diet 1 
<take back the indent 
       |-> [ID: 1] Program 
<take back the indent 

问题:我做错了什么,缩进不是他们应该的?

+0

你总是递增之前调用5,所以'tab- = 5'被取消。快速解决方法是做'tab- = 10;' – mtijanic

回答

1

在每次迭代中,您将要添加5到tab

而是变异tab的,传递正确的价值功能,让递归处理:

if (copy_handle->pInner != NULL) 
{ 
    rec_printn(copy_handle->pInner, tab + 5); 
} 
else if (copy_handle->pNext == NULL) 
{ 
    printf("<take back the indent\n"); 
} 

这将确保tab总是有“此级别”的值相同。

(也就是说,而不是想“增加缩进,然后打印一个新的水平”,认为“有了更深的压痕打印一个新的水平”,如果你明白我的意思。)

+0

太棒了!解决了我的问题。我会认为这个函数不会“记住”它是以前的选项卡级别,我不完全明白它为什么会这样做? –

+1

@ShadyProgrammer函数的每次调用都有自己的变量,称为“tab”,它们是完全独立的。 (它的工作原理与如果您以非递归方式调用完全不同的函数完全相同 - 即使碰巧有一个局部变量或称为“tab”的参数,也不会发生。)由于您从不为'tab'指定新值,在“这个级别”上,它不会改变。 – molbdnilo

+0

哦,我现在明白了,谢谢。作为一个旁观者和好奇心的问题:我能否在没有递归的情况下做到这一点?我遇到的主要问题是在打印完列表后,指针地址被覆盖,并且列表出现损坏,因此我在第一个示例中为每个深度使用了单独的变量。 –