2013-08-27 147 views
6

我該如何去除鏈接列表中的節點?C從鏈表中刪除節點

這裏是我的代碼:

void RemoveNode(Node * node, Node ** head) { 
    if (strcmp(node->state, (*(*head)->next).state) == 0) { 
     Node * temp = *head; 
     *head = (*head)->next; 
     free(temp); 
     return; 
    } 

    Node * current = (*head)->next; 
    Node * previous = *head; 
    while (current != NULL && previous != NULL) { 
     if (strcmp(node->state, (*current->next).state) == 0) { 
      Node * temp = current; 
      previous->next = current->next; 
      free(temp); 
      return; 
     } 
     current = current->next; 
     previous = previous->next; 
    } 
    return; 
} 

但我不斷收到賽格故障。

我覺得我在做一些愚蠢的事情....任何想法?

+1

爲什麼'previous = previous-> next'而不是'previous = current'在重新分配當前之前? –

+0

另外,如果出現段錯誤,請在調試器中運行程序。它會在你遇到問題的地方停下來,讓你檢查一下調用堆棧和變量。至少你應該編輯你的問題以包含調用堆棧,並指出在提供的代碼中崩潰發生的位置。 –

+0

另外,你是否總是*有一個有效的'(* head) - > next'指針?如果清單是空的呢?如果列表中只有一個節點會怎麼樣? –

回答

5

我的猜測:

void RemoveNode(Node * node, Node ** head) { 
    if (strcmp(node->state, ((*head)->state) == 0) { 
     Node * temp = *head; 
     *head = (*head)->next; 
     free(temp); 
     return; 
    } 

    Node * current = (*head)->next; 
    Node * previous = *head; 
    while (current != NULL && previous != NULL) { 
     if (strcmp(node->state, current->state) == 0) { 
      Node * temp = current; 
      previous->next = current->next; 
      free(temp); 
      return; 
     } 
     previous = current; 
     current = current->next; 
    } 
    return; 
} 
+4

如果你指出你改變了什麼,它會更有幫助。 –

+0

我改變了與'next'值的比較以僅僅是當前值,並且我改變了while循環中前面的更新。 – Jiminion

+0

謝謝,這就是它! – Travv92

2

我建議你試着用遞歸這樣做,以避免「雙指針」的需要。它將極大地簡化邏輯。 This link有一個非常好的解釋和遞歸執行此操作的實現。如果您試圖從空的鏈表中刪除節點,這個特別的工具甚至可以工作。

Node *ListDelete(Node *currP, State value) 
{ 
    /* See if we are at end of list. */ 
    if (currP == NULL) 
    return NULL; 

    /* 
    * Check to see if current node is one 
    * to be deleted. 
    */ 
    if (currP->state == value) { 
    Node *tempNextP; 

    /* Save the next pointer in the node. */ 
    tempNextP = currP->next; 

    /* Deallocate the node. */ 
    free(currP); 

    /* 
    * Return the NEW pointer to where we 
    * were called from. I.e., the pointer 
    * the previous call will use to "skip 
    * over" the removed node. 
    */ 
    return tempNextP; 
    } 

    /* 
    * -------------- RECURSION------------------- 
    * Check the rest of the list, fixing the next 
    * pointer in case the next node is the one 
    * removed. 
    */ 
    currP->next = ListDelete(currP->next, value); 


    /* 
    * Return the pointer to where we were called 
    * from. Since we did not remove this node it 
    * will be the same. 
    */ 
    return currP; 
}