2014-12-06 74 views
0

我試着去理解下面的代碼:傳遞指針地址在遞歸函數在C

void recursiveReverse(struct node **head_ref) 
{ 
    struct node *first; 
    struct node *rest; 

    if (*head_ref == NULL) 
     return; 

    first = *head_ref; 
    rest = first->next; 
    if (rest == NULL) 
     return; 
    recursiveReverse(&rest); 
    first->next->next = first; 
    first->next = NULL;   
    *head_ref = rest;  
} 

我注意到變量rest是具有用於所有的遞歸調用相同的值,一旦代碼超越recursiveReverse(&rest)達到。但first->next有不同的值。我能夠理解爲什麼first->next通過將它們寫入堆棧並將它與每個調用進行比較而具有不同的值。但我無法理解rest對於所有呼叫的值是多少,而不是來自堆棧的(rest = first->next)。如果問題不清楚或需要任何細節,請告訴我。 感謝

更新:我注意到,妥善安排參數,如果我叫recursivereverse(休息),而不是rev​​ursivereverse(&休息),對於每一個遞歸調用就像revursion堆棧上的任何其他變量,其餘值的變化。我不明白休息在通話中有什麼不同&。

+1

執行'recursiveReverse(&rest);'''執行後,列表幾乎相反,此時'rest'指向列表的最後一項,無論遞歸中的嵌套層次如何,它都是相同的 – 2014-12-06 06:51:07

回答

2

考慮以下輸入。

首先遞歸,

*Head_ref = 1;//value of head_Ref 
first =1; // first=*head_ref; 
rest=2;// rest=first->next; 

第二遞歸,

*Head_ref = 2;//value of head_Ref 
first =2; // first=*head_ref; 
rest=3;// rest=first->next; 

第三遞歸。

*Head_ref = 3;//value of head_Ref 
first =3; // first=*head_ref; 
rest=4;// rest=first->next; 

四遞歸,

*Head_ref = 4;//value of head_Ref 
first =4; // first=*head_ref; 
rest=NULL;// rest=first->next; 

條件失敗,它來到第三遞歸,它叫。

三遞歸,

first=3; 
    first->next->next=first// here it means the rest link. 
    first->next=NULL;// it will make the pointer that is end. 
    *head_ref=rest; // making the starting address in this recursion 

現在列表中就這樣產生了,4 - > 3。現在剩下的值改爲4

現在它來到了第二遞歸,

其餘部分將指向4,但一線>未來指向3

first=2; 
rest=4; 
first->next->next=first// here it means the rest link. 
first->next=NULL;// it will make the pointer that is end. 
*head_ref=rest; // making the starting address in this recursion 

所以現在頭_ref指向4.然後現在的名單將在4 - > 3 - > 2。

談到第一遞歸,

這裏,

first=1,rest=4, But first -> next =2. 
first->next->next=first// here it means the rest link. 
first->next=NULL;// it will make the pointer that is end. 
*head_ref=rest; // making the starting address in this recursion 

在最後它變成

4 -> 3 -> 2 -> 1. 

所以現在列表是顛倒的。這裏主要是讓*head_ref在遞歸結束時進入最後位置。

+0

嗨,但在第二次遞歸調用中,我們在調用堆棧上,在遞歸之前我們有rest = first-> next。因此,休息應該有什麼值,首先 - >下一個是正確的?..我觀察到的另一件事是,如果我調用reverse(rest)而不是rev​​erse(&rest),那麼程序不會以這種方式行爲 – user1455116 2014-12-06 08:11:06

+0

在遞歸休息之前有你說的值。在遞歸中,我們傳遞其餘的地址。另一件事,即使rest被改變,它的值,第一個指針指向位置不會改變。 – 2014-12-06 08:35:12

0

考慮一個鏈表1->2->3->4。根據recursiveReverse(),在(rest == NULL)滿足(節點'4')時,在遞歸函數調用的迭代中,*head_ref = 4;現在在此之後,調用返回到先前的迭代(節點'3')。這裏基本上rest(='4')函數遞歸當前迭代的變量(節點'3')實際上是最後一次迭代的*head_ref(最後一個節點'4'),其中*head_ref被計算爲4.因此,在函數的末尾在遞歸(節點'3')中,我們正在做*head_ref = rest;,即。 *head_ref = 4,因爲從函數迭代節點='4'接收rest作爲4。現在在這些函數的下一個連續遞歸返回時,返回地址*head_ref,它保持相同,因此語句*head_ref = rest;給出了相同的值。