2013-08-27 13 views
6

Jak mogę usunąć węzeł z połączonej listy?C Usuń węzeł z połączonej listy

Oto mój kod:

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; 
} 

ale wciąż otrzymuję błędy SEG.

Czuję, że robię coś głupiego .... Jakieś pomysły?

+1

Dlaczego "poprzedni = poprzedni-> następny" zamiast tylko "poprzedni = bieżący" przed ponownym przypisaniem bieżącego? –

+0

Ponadto, jeśli wystąpią błędy segmentacji, uruchom program w debugerze. Zatrzyma się w miejscu, w którym masz problem, i pozwoli ci na zbadanie listy połączeń i zmiennych. Przynajmniej powinieneś edytować swoje pytanie, aby dołączyć do niego listę połączeń i wskazać, gdzie w dostarczonym kodzie następuje awaria. –

+0

Czy też zawsze masz * prawidłowy wskaźnik '(* head) -> next'? Co jeśli lista jest pusta? Co jeśli na liście jest tylko jeden węzeł? –

Odpowiedz

5

Zgaduję:

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

Byłoby bardziej pomocne, gdybyś wskazał, co zmieniłeś. –

+0

Zmieniłem porównanie z "następną" wartością do aktualnej wartości i zmieniłem aktualizację poprzedniego w pętli while. – Jiminion

+0

Dzięki, to było dokładnie to! – Travv92

2

Polecam, aby spróbować to zrobić z rekursji, aby uniknąć konieczności „podwójnej wskaźnik”. To bardzo uprości logikę. This link ma bardzo dobre wytłumaczenie i implementację robienia tego rekurencyjnie. Ten konkretnie zadziała nawet, jeśli spróbujesz usunąć węzeł z pustej, połączonej listy.

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; 
}