2013-08-27 149 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; 
}