2011-03-24 91 views
1
void add(llist *list, lnode *newNode){ 
    list->size++; 
    addRecursion(&list->head, newNode); 
} 

lnode* addRecursion(lnode **node, lnode *newNode){ 
    if(*node == NULL){ 
     *node = newNode; 
    } 
    else{ 
     lnode *nextNode = (*node)->next; 
     (*node)->next = addRecursion(&nextNode, newNode); 

    } 
    return *node; 
} 

此代碼正常工作..我在網上查看了代碼並做了一些更改。但我仍然不明白爲什麼addRecursion函數必須具有返回類型。我改變了功能類似鏈接列表遞歸...爲什麼我需要return語句?

void addRecursion(lnode **node, lnode *newNode){ 
     if(*node == NULL){ 
      *node = newNode; 
     } 
     else{ 
      lnode *nextNode = (*node)->next; 
      addRecursion(&nextNode, newNode); 

     } 
    } 

然後它沒有工作..

+0

如果你檢查返回的是什麼,以及在良好函數結束時保存了什麼lnode – Ryan 2011-03-24 23:42:46

回答

2

它總是返回它存儲在* node中的值,並且在修改後的代碼中它會丟失該值,因爲遞歸調用會傳遞一個本地temp,而不是實際需要放置該值的地方,然後執行store它返回。一個非常奇怪的構造。您可以addRecursion空穴(和簡單),如果你只是擺脫局部變量的:

void addRecursion(lnode **node, lnode *newNode){ 
    if(*node == NULL){ 
     *node = newNode; 
    }else{ 
     addRecursion(&(*node)->next, newNode); 
    } 
} 
1

要分配的東西(*node)->next。這指向列表中的下一個節點,我想。因此,如果沒有分配,列表不會進入最後一個節點,新節點將被添加到該節點。遞歸可以用迭代代替。

1

因爲函數返回算法中需要的下一個節點的地址來設置最終節點。

1

隨着遞歸的進行,可能會幫助將調用堆棧的增長/收縮可視化。假定以下列表:

node1 -> node2 -> node3 -> null 

addRecursion然後展開如下(僞碼):

addRecursion(&node1, newNode) 
    node1.next = addRecursion(&node2, newNode); 
     node2.next = addRecursion(&node3, newNode); 
      node3.next = addRecursion(null, newNode); // returns &newNode 
      node3.next = &newNode; 
     node2.next = &node3; 
    node1.next = &node2; 
// return value ignored 

新節點被添加到結束,並在鏈中的每個鏈接被保留。

0

還應該工作,如果你做這個調整你的代碼,你重新分配的nextNode值回(*node)->next因爲你通過引用傳遞該值遞歸函數調用(因此它是在後來的遞歸調用修改):

void addRecursion(lnode **node, lnode *newNode) 
{ 
    if(*node == NULL) 
    { 
     *node = newNode; 
     return; 
    } 

    lnode *nextNode = (*node)->next; 
    addRecursion(&nextNode, newNode); 
    (*node)->next = nextNode; //Add this line to re-connect the link 
} 

上述克里斯的版本是有點清潔,雖然因爲軸了兩次任務,這樣做由於沒有本地指針var所需的存儲空間,所以也節省了一些空間有效的nextNode