当前位置: 首页 > 知识库问答 >
问题:

如何从循环单链表中删除节点

暨嘉
2023-03-14

我在以递归方式从循环单链表中删除单个节点/值时遇到了一些问题(当然,如果可能的话)。我的代码只从中间删除,而不是从第一个或最后一个地方删除。

在以递归方式删除其中一个连接后,我不知道如何建立连接。我的意思是,如果我要删除第一个元素,那么我需要将最后一个节点连接到下一个节点。

这是我的代码:

Node *ListDelete(Node *list, Node *tail, int val, Node **deleted) {
    if (!list || (list == tail && list->value != val)) {
        *deleted = NULL;
        return list;
    }

    if (list->value == val) {
        *deleted = list;
        return list->next;
    }

    list->next = ListDelete(list->next, tail, val, deleted);
    return list;
}

参数和返回:

        case MENU_DELETE:
            val = GetValue("Enter value");
            if (list) tail = FindTail(list);
            list = ListDelete(list, tail, val, &node);
            ListPrintNode(node, "Deleted");
            free(node);

查找尾部功能:

Node* FindTail(Node* list)
{
    Node* temp = list;
    while(temp->next != list)
        temp = temp->next;
    return temp;
}

共有1个答案

端木宏盛
2023-03-14

ListDelete的API有一个不需要的尾部参数。

这里是一个没有这样一个参数的实现。它返回指向循环列表的指针,其中第一个节点的值==val列表开始-

Node *ListDelete(Node *list, int val, Node **deleted) {
    // special case empty and singleton lists
    if (!list || (list == list->next && list->value != val)) {
        *deleted = NULL;
        return list;
    }
    if (list == list->next) {
        *deleted = list;
        return NULL;
    }
    for (Node *node = list;; node = node->next) {
        if (node->next->value == val) {
            *deleted = node->next;
            node->next = node->next->next;
            if (list == *deleted)
                list = node->next;
            return list;
        } else
        if (node->next == list)
            *deleted = NULL;
            return list;
        }
    }
}

对于您的API,以下是代码的更正版本:

Node *ListDelete(Node *list, Node *tail, int val, Node **deleted) {
    if (!list || (list == list->next && list->value != val)) {
        *deleted = NULL;
        return list;
    }
    if (list == list->next) {
        *deleted = list;
        return NULL;
    ]
    if (list->next->value == val) {
        *deleted = list->next;
        list->next = list->next->next;
        return list;
    }
    if (list == tail) {
        *deleted = NULL;
        return list;
    }
    ListDelete(list->next, tail, val, deleted);
    if (list == *deleted)
        list = list->next;
    return list;
}

这种递归实现的缺点是递归的深度是列表的长度。此递归不是尾部递归,因此足够长的列表将导致堆栈溢出。

为了避免这种情况,可以将函数转换为非递归函数:

Node *ListDelete(Node *list, Node *tail, int val, Node **deleted) {
    // special case empty and singleton lists
    if (!list || (list == list->next && list->value != val)) {
        *deleted = NULL;
        return list;
    }
    if (list == list->next) {
        *deleted = list;
        return NULL;
    }
    for (Node *node = list;; node = node->next) {
        if (node->next->value == val) {
            *deleted = node->next;
            node->next = node->next->next;
            if (list == *deleted)
                list = node->next;
            return list;
        } else
        if (node == tail) { // equivalent to if (node->next == list)
            *deleted = NULL;
            return list;
        }
    }
}

 类似资料:
  • 我理解得对吗?(从虚拟节点开始) dummy->a->b->c->d->dummy(环绕到dummy节点) 因此,如果我想删除第一个实际的数据段(A),我需要将它分配给一个临时变量。所以Node first=head.next。然后我需要有一个虚拟的头部引用“B”,所以我需要做head.next=first.next。这就是所有需要做的吗? 在从列表中删除任何节点N的情况下(假设它在列表中),这是

  • 我有一个基本的链表问题,我在下面试图解决。如果您能为我的方法、算法的正确性(甚至是编码风格)提供任何信息,我将不胜感激。该问题需要一个函数,该函数删除循环链表中所有出现的int,并返回列表中的任何节点或NULL(当列表为NULL时)。 以下是我目前掌握的一些C代码:

  • 问题内容: 这段代码是一个表,可以选择“惰性名称”,“删除”,“显示”和“退出”。 该代码运行良好,但是我唯一的问题是如何删除节点中的所选名称 *我不知道如何删除节点。我应该在删除方法上加上什么? 问题答案: 要删除Node,您实际上需要更新它的上一个节点的位置以删除Node的位置,而剩下的Node最终将被垃圾回收。 如果要删除的节点是根节点,则只有一个问题,然后更新根节点。

  • 我有一个单链表。如果我想从这个链表中删除一个已知的元素,我能做什么? 例如:节点*头;(44)节点*尾部;(39) 链接列表:44 27 59 13 45 39我们想从中删除45。得到:4427591339 我只知道从列表中删除第一个元素(如果元素(需要删除)是列表的第一个元素)。我得到了:头=头- 如何从列表中删除中间节点?

  • 问题内容: 我在面试中被问到以下问题:“如何检测链表中的循环?”,我解决了这个问题,但立即面试官问我如何删除链表中的循环。我摸索了 那么关于如何解决这个问题的任何指针,可能是伪代码还是方法定义? 我对Java很满意,因此已在Java下标记了这个问题。 对于实例,此链接列表具有循环 问题答案: 此问题有两个部分: 检测列表中是否存在循环 确定循环的开始 一旦知道了循环的开始位置,就很容易识别列表中的

  • 我试图从基于阉羊的双链表中删除一个元素,该列表中的节点满足返回bool的函数。由于某种原因,替换节点的前一个指针(下一个被删除)不更新,而是引用回它自己。 我的代码 测试结果