2015-01-05 74 views
0

任何人都可以解釋這是如何實際工作的。我無法理解遞歸,遞歸到達鏈表末尾後會發生什麼,以及隨着操作(增量和條件檢查)如何展開?使用遞歸結束(鏈接列表)的第n個節點

Linked List

void printNthFromLast(struct node* head, int n) 
{ 
static int i = 0; 
if(head == NULL) 
    return; 
printNthFromLast(head->next, n); 
if(++i == n) 
    printf("%d", head->data); 
} 
+1

請注意,該功能只能被稱爲*一次*。變量「i」的初始化僅在第一次調用該函數時發生。 –

+0

如果你能夠理解任何簡單的遞歸,那麼它的簡單... – Ankur

回答

0

如果傳遞給它的struct node爲NULL,則函數返回。如果鏈表中有零節點或者我們已經到達鏈表的末尾,就會發生這種情況。

if(head == NULL) 
    return; 

否則,函數的每個實例都將在這條線就被等候的「孩子」返回:

printNthFromLast(head->next, n); 

沒有印刷完成,直到我們到達列表的末尾。一旦我們已經達到列表的末尾,調用的最終函數將返回if語句,因爲head == NULL,因爲我們在最後。

功能的每個實例現在將着手執行這些行(一旦它的「孩子」已恢復):

if(++i == n) 
    printf("%d", head->data); 

它基本上從後面計數。每個實例將i遞增1,然後檢查它是否等於我們提供的數量n。如果是,它將打印數據。否則,它只是結束,它的'父'有機會執行這些行。

編輯:這真的是一個非常糟糕的方式來做你正在做的事情。如果列表相當大,您的程序可能會耗盡堆棧內存。你應該通過迭代來做到這一點。

0

這在我看來是這樣做不好功能,但我會試着解釋我怎麼看它。

基本上,您將多個遞歸函數推入堆棧中,直到遇到基本情況爲止,但您只是每次彈出大約一半的函數,剩下的部分在下一個函數之後完成。當你點擊基本情況時,不會有更多的遞歸發生,你必須回到堆棧中,彈出每個函數,直到你在父函數中,它會完成並完成。

+0

爲什麼做得不好? – Ankur