2015-11-17 159 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

哦,我現在明白了,謝謝。作爲一個旁觀者和好奇心的問題:我能否在沒有遞歸的情況下做到這一點?我遇到的主要問題是在打印完列表後,指針地址被覆蓋,並且列表出現損壞,因此我在第一個示例中爲每個深度使用了單獨的變量。 –