从链表中删除节点

7

我该如何从链表中删除一个节点?

这是我的代码:

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 - Some programmer dude
此外,如果您遇到分段错误,请在调试器中运行程序。它将在您的问题所在处停止,并让您检查调用堆栈和变量。至少您应该编辑您的问题以包括调用堆栈,并指出提供的代码中崩溃发生的位置。 - Some programmer dude
此外,您是否始终拥有有效的 (*head)->next 指针?如果列表为空怎么办?如果列表中只有一个节点呢? - Some programmer dude
我不理解与“next”节点的比较。似乎会错过一些节点,是的,可能会运行具有NULL next ptr的轨迹。 - Jiminion
2个回答

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

5
如果您指出您所做的更改,将会更有帮助。 - Some programmer dude
我将比较与“下一个”值改为仅使用当前值,并且我更改了while循环中的previous更新。 - Jiminion

2
我建议您尝试使用递归来完成此操作,以避免需要使用“双指针”。这将极大地简化逻辑。此链接提供了一个非常好的递归解释和实现。特别是,即使您尝试从空链表中删除节点,此方法也可以正常工作。
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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接