2011-10-28 32 views
0

這是我實現計數:錯誤,試圖計算在循環雙向鏈表中的節點遞歸

int count(node *start) 
{ 
    static int l ; 
    node *current;   /* Node for travelling the linked list*/ 
    current=start; 
    if(current->next!=start) 
    { 
     l = 1 + count (current->next) ; 
     return (l) ; 
    } 


    else 
    { 
     return(1); 
    } 
} 

下面是主要功能的片段在那裏我稱之爲:

void main() 
{ 
    node *head; 
printf ("Length of linked list = %d", count (head)) ; 
} 

這裏是結構:

struct cirdoublelinklist 
{ 
    struct cirdoublelinklist *prev; /** Stores address of previous node **/ 
    int value;     /** stores value **/ 
    struct cirdoublelinklist *next; /** stores address of next node **/ 
}; 

/** Redefining list as node **/ 
    typedef struct cirdoublelinklist node; 

在運行並試圖查看列表的長度,它崩潰與b記憶力。請幫我解決這個問題,現在我已經研究了很長時間了。後指定的位置

void initialize(node *start) 
{ 
    start->prev=start; 
    printf("\nEnter Value\n"); 
    scanf("%d",&start->value); 
    start->next=start; 
} 

方法來添加後續節點:

方法添加的第一個節點

void insert_after(node *start) 
{ 
    int num;     /* value for inserting a node */ 
    int flag=0; 
    node *newnode;   /* New inputed node*/ 
    node *current;   /* Node for travelling the linked list*/ 
    newnode=(node*)malloc(sizeof(node)); 
    printf("\nEnter the value after which you want to insert a node\n"); 
    scanf("%d",&num); 
    init(newnode); 
    current=start; 
    while(current->next!=start) 
    { 

     if(current->value==num) 
     { 
      newnode->next=current->next; 
      current->next->prev=newnode; 
      current->next=newnode; 
      newnode->prev=current; 
      flag=1; 
     } 
     current=current->next; 
    } 
    if(flag==0 && current->next==start && current->value==num) 
    { 
     /*** Insertion checking for last node ***/ 
     newnode->next=current->next;  /* Start is being copied */ 
     current->next->prev=newnode; 
     current->next=newnode; 
     newnode->prev=current; 
     flag=1; 
    } 
    if(flag==0 && current->next==NULL) 
     printf("\nNo match found\n"); 
} 
+0

你爲什麼要把'l'靜態的?這只是防止函數完全重入,這通常是正確遞歸的要求。 –

回答

1

每次調用count的時候,它有一個新的start,所以current->next!=start總是比較一個節點到它的繼承者,這隻會永遠結束如果列表長度1.什麼你最有可能想要做的是有兩個功能:

int count(node *start) 
{ 
    if(start == NULL) 
     return 0; 
    return count_helper(start, start); 
} 

int count_helper(node *start, node *current) 
{ 
    static int l; 
    if(current->next!=start) 
    { 
     l = 1 + count (start, current->next); 
     return (l) ; 
    } 
    else 
    { 
     return(1); 
    } 
} 

正如其他人所說,靜態變量是沒有必要的。

int count_helper(node *start, node *current) 
{ 
    if(current->next!=start) 
    { 
     return 1 + count (start, current->next); 
    } 
    else 
    { 
     return 1; 
    } 
} 

最後,更有效的實現將非遞歸:寫作就是我所說的count_helper將是一個更好的辦法

int count(node *start) 
{ 
    if(start == NULL) 
     return 0; 
    node *current = start->next; 
    int c = 1; 
    while(current != start) 
    { 
     c++; 
     current = current->next; 
    } 
    return c; 
} 
+0

非常感謝亞倫,這真的很有幫助。現在我已清除我的概念 – user1017072

+0

@ user1017072請注意編輯到非遞歸版本以捕獲length = 0的情況。另外,如果你接受了你認爲最能回答你的問題的答案,那將會很有幫助。 –

+0

@ Aaron-dufour我認爲非遞歸版本是錯誤的。在** while循環之前,_current_和_start_是相等的,所以它不會進入循環,它應該是一個do-while循環。 –

1

好了,問題是,你調用該函數在主上空指針。 Infact node *head;已被聲明,但從未被分配給某物。所以,當你執行這條線:

if(current->next!=start) 

程序崩潰,因爲它會檢查NULL->next,很明顯,不存在。

+0

我也有一種方法,基本上將數據值插入節點。但即使在創建新節點後,它似乎也失敗了。對於第一個節點,它給出了正確的長度1(即它到了else塊),但是對於第二個節點,它在到達if(current-> next!= start)時崩潰,我應該做什麼在創建節點的函數中進行一些初始化?感謝您的幫助 – user1017072

+0

@ user1017072那麼,在這種情況下,您應該向我們展示添加數據的功能。此外,刪除行static int l;因爲它是無用的,並改變if只需返回1 + count(current-> next);這是具有遞歸功能的正確方法。 –

+0

嗨,我編輯了問題的方法插入初始節點,然後後續節點。我嘗試去除您指定的靜態,但仍然失敗,出現內存不足的問題。還有什麼建議?感謝您的時間和支持 – user1017072

0

簡而言之,遞歸調用不知道原始的開始節點。您將需要添加第二個參數node*並通過它傳遞開始節點。

+0

嗨Ignacio,我應該在哪裏添加第二個節點,以及如何傳遞開始節點。我很抱歉聽起來像一個noob,但你能告訴我如何糾正它,我無法理解。非常感謝您的幫助 – user1017072

+0

在函數原型中。在函數調用中。 –

1

你需要傳遞一個指針insert_after功能開始指針

void insert_after(node **start) 

,而不是

void insert_after(node *start) 

否則你只是更新*啓動的本地副本。

同樣,對於初始化

void initialize(node **start)