2017-07-18 106 views
-2

我需要用C來寫一個函數,給定一個指針鏈表,將打印出Python語法元素:例如對於由1,2,3,4和5組成的列表,該功能將打印出[1,2,3,4,5]。Ç - 使用遞歸打印鏈表

我試圖寫的代碼如下:

struct node { 
    struct node *next; 
    int  data; 
}; 

void print_list(struct node *list) { 
    printf("["); 
    if (list == NULL) { 
     printf("]"); 
    } else { 
     printf("%d", list->data); 
     if (list->next != NULL) { 
      printf(", "); 
     } 
     print_list(list->next); 
    } 
} 

輸出看起來像這樣:[1,[2,[3,[4,[5 []

據我所知,每函數調用自己的時間,「[」將被打印。有沒有辦法在第一次調用函數時打印「[」?

+0

如何在打印之前激活調用遞歸函數? – Ctx

+0

像之前調用void print_list? –

+0

是的。第二個選項,添加一個標誌,告訴您該parmeters如果你要打印托架 – CIsForCookies

回答

5

您可以爲印刷括號的包裝功能。在印刷之間,調用實際的遞歸函數,就像這樣:

void print_list(struct node *list) { 
    putchar('['); 
    print_list_helper(list); 
    putchar(']'); 

void print_list_helper(struct node *list) { 
    if (list != NULL) 
     printf("%d", list->data); 
     if (list->next != NULL) { 
      printf(", "); 
     } 
     print_list_helper(list->next); 
    } 
} 

編輯:作爲pointed out由費利克斯Palmen,一個static變量是一種選擇,但不是最好的。它僅在您第一次調用該函數時有效。之後,計數器必須重置,這不容易做,並使遞歸函數不純。

使用static的一個例子:

#include <stdio.h> 

void foo() { 
    static int x = 0; 
    printf("x In foo: %d\n", x); 
    x++; 
} 

int main() { 
    int i; 
    for(i = 0; i < 5; i++) { 
     foo(); 
    } 

    return 0; 
} 

此打印:

$ ./a.out 
x In foo: 0 
x In foo: 1 
x In foo: 2 
x In foo: 3 
x In foo: 4 

靜態整數在函數調用之間保持其值。因此,您可以在第一次調用遞歸函數時使用它,但每次遇到基本情況時都需要重置該函數。

static又如:

void foo() { 
    static int x = 0; // initialization (done ONCE!) 
    printf("x In foo: %d\n", x); 
    x++; 
    if(x%2 == 0) x = 0; // reassignment (done as many times as you like) 
} 
... // everything else is the same 

這給:

$ ./a.out 
x In foo: 0 
x In foo: 1 
x In foo: 0 
x In foo: 1 
x In foo: 0 
+0

是否可以在不創建包裝函數或全局變量的情況下解決問題? –

+0

好主意,但'_print_list'這個名稱很差(因爲以下劃線開頭的標識符是實現保留的)。應該是'print_list_content' –

+0

@ M.Ng它是一個靜態整數變量。我不想聽起來多餘,因爲[this](https://stackoverflow.com/a/45167070/4909087)答案已經提出了它。 –

0

使用全局變量和更改您的代碼

int count=0; 
void print_list(struct node *list) { 
    if(count==0) 
     printf("["); 
    if (list == NULL) { 
     printf("]"); 
    } else { 
     printf("%d", list->data); 
     if (list->next != NULL) { 
      printf(", "); 
     } 
     print_list(list->next); 
    } 
count++; 

} 
1

你可以用一個靜態的整數做到這一點。

struct node { 
    struct node *next; 
    int  data; 
}; 

void print_list(struct node *list) { 
    static int print_start = 0; 
    if (print_start == 0) { 
     printf("["); 
    } 
    if (list == NULL) { 
     printf("]"); 
     print_start = 0; 
    } else { 
     print_start++; 
     printf("%d", list->data); 
     if (list->next != NULL) { 
      printf(", "); 
     } 
     print_list(list->next); 
    } 
} 
+3

您在打印右括號時還必須設置print_start = 0 –

+0

好的解決方案。 +1 –

+1

如果這是爲了練習遞歸,我不認爲這是一個好的解決方案。遞歸函數通常旨在成爲*純函數,而全局變量則是失敗的目的。另一方面,如果不需要遞歸,則有更好的迭代方法。 –

0

添加一個附加參數,顯示它是從外部還是遞歸調用。最優雅的方式,但會花費你一些堆棧。