【问题标题】:C Remove node from linked listC 从链表中删除节点
【发布时间】:2013-08-30 05:38:30
【问题描述】:

如何从链表中删除节点?

这是我的代码:

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

但我不断收到段错误。

我觉得我在做一些愚蠢的事情......有什么想法吗?

【问题讨论】:

  • 为什么previous = previous->next 而不是previous = current 在重新分配电流之前?
  • 另外,如果您遇到分段错误,请在调试器中运行您的程序。它会在您遇到问题的地方停止,并让您检查调用堆栈和变量。至少您应该编辑您的问题以包含调用堆栈,并指出在提供的代码中发生崩溃的位置。
  • 另外,您总是有一个有效的(*head)->next 指针吗?如果列表为空怎么办?如果列表中只有一个节点怎么办?
  • 我不明白与“下一个”节点的比较。似乎某些节点可能会丢失,是的,可能会在下一个 ptr 为 NULL 的情况下运行 rails。

标签: c pointers linked-list nodes


【解决方案1】:

我的猜测:

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

【讨论】:

  • 如果您指出您所做的更改会更有帮助。
  • 我将与“下一个”值的比较更改为仅当前值,并在 while 循环中更改了上一个的更新。
  • 谢谢,就是这样!
【解决方案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;
}

【讨论】:

    猜你喜欢
    • 2017-10-21
    • 2019-05-10
    • 1970-01-01
    • 2021-02-21
    • 1970-01-01
    • 2019-05-10
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多