2013-08-27 8 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 = current' 대신'previous = previous-> next '를 사용하는 이유는 무엇입니까? –

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