2015-10-06 158 views
-2

我有這個程序,它具有創建列表的功能,刪除一個節點,如果它的值等於功能delete_node()的參數x,然後它打印鏈表節點。創建和打印工作正常,但我無法刪除值爲x的節點。我得到我的原始列表或空白列表。C刪除鏈接列表中的節點

#include <stdio.h> 

struct list { 
    int value; 
    struct list *next; 
}; 

struct list *create_list(struct list *l, int x) { 

    //allocate memory for new tmp node 
    struct list *tmp = malloc(sizeof(struct list)); 

    tmp->value = x; 

    //tmp shtohet ne koke te listes 
    tmp->next = l; 

    //l behet koka e listes 
    l = tmp; 


    return l; 
} 

struct list *delete_node(struct list *l, int x) { 

    while (l) { 
     if(l->value == x) { 
      //printf("%d", x); 
      struct list *tmp = malloc(sizeof(struct list)); 

      tmp->value = l->next->value; 
      tmp->next = l->next->next; 
      l = tmp; 

      printf("%d ", tmp->value); 

     } 

     l = l->next; 
    } 

    return l; 

} 

int main() { 

    struct list *l = NULL; 

    for (int i=5; i>-6; --i) 
     l = create_list(l, i); 

    l = delete_node(l, 3); 

    while (l) { 
     printf("%d ", l->value); 
     l = l->next; 
    } 

    printf("\n"); 

    return 0; 
} 
+1

你正在遍歷鏈表,直到你到達結尾,因此當列表中的任何地方沒有找到'x'時,'return l'將返回NULL。當找到'x'時,你扔掉原始記錄並返回下一條記錄的副本,最後扔掉2條記錄,然後繼續遍歷列表的其餘部分,最後返回NULL。 – alvits

回答

2

下面是對有問題的代碼的修復。

struct list *delete_node(struct list *l, int x) { 
    struct list *prev, *retval=l; 
    while (l) { 
     if(l->value == x) { 
      if(l==retval) { 
       retval=l->next; 
       free(l); 
       l=retval; 
      } else { 
       prev->next=l->next; 
       free(l); 
       l=prev; 
      } 
     } 
     prev = l; 
     l = l->next; 
    } 

    return retval; 
} 

您不需要分配更多內存來丟棄不需要的節點。你這樣做會嚴重泄漏記憶。

您需要跟蹤列表的頭部。這是retval的用途。如果x未找到或在非頭節點中找到,則您將返回相同的頭部。如果在頭節點中找到x,您將返回下一個節點。

您還需要跟蹤前一個節點,以便能夠告訴前一個節點當前節點將被釋放。這對單鏈表是必需的。

+0

謝謝@alvits –

1

刪除的關鍵是跟蹤以前的模式。

通過凝視「假」頭節點,簡化了while循環。

struct list *delete_node(struct list *l, int x) { 
    struct list start; // Code only uses the next field 
    start.next = l; 
    struct list *p = &start; 
    while (p->next) { 
     struct list *q = p->next; 
     if (q->value == x) { 
     p->next = q->next; 
     free(q); 
     break; 
     } 
     p->next = q; 
    } 
    return start.next; 
    }