【问题标题】:Delete a node from a singly linked list从单链表中删除一个节点
【发布时间】:2013-11-03 14:58:23
【问题描述】:

我有这个问题: 给定一个单链表 L,其中 L 中的每个节点都存储一个整数键,以及指向 L 中下一个节点的指针。最后一个节点的下一个节点设置为 NULL。 给你一个指针 ptr 指向存储键 k 的节点,它不是列表中的最后一个节点。 展示如何从列表中删除键 k 给定 ptr 指向包含 k 的节点的指针;您的算法应该具有时间复杂度 O(1),即它应该与列表的长度无关。假设你有指向 L 的头和尾节点的指针。

我知道如果我们有一个双向链表,我们可以在 O(1) 时间复杂度内删除节点, 但是我们如何在单链表中做到这一点? 我们不是必须遍历所有列表才能找到它之前的节点吗?

【问题讨论】:

  • 我猜这是一个作业。如果是这样,请不要作弊:查看课程材料,答案将很简单。这就像 3 行 C 代码,除非您对 编写的代码有特定 问题,否则我不会给您答案。
  • 这是不可能的。
  • @StefanoSanfilippo 首先这不是作业,我下周有期中考试,我正在尝试解决一些额外的问题。其次,除非我很难尝试,否则我不会发布这个问题解决它..这些是我的想法:如果我有一个双向链表,为了删除一个具有指向其节点的指针的元素,我可以简单地执行以下操作:ptr->previous->next = ptr->下一个 ;但在单链表中不是这样!
  • @aschepler 我也开始这么想了 :(
  • 这里有一个线索:@aschepler 是对的。在 O(1) 中是不可能解决的,因为需要在 O(n) 中搜索前一个节点(不能直接从节点指针中获取)。但是你可以在 O(n) 中解决它:首先你找到前面的节点,然后在 O(1) 中得到下一个节点,然后像在双链表中一样删除。

标签: c++ linked-list time-complexity


【解决方案1】:

考虑 A -> B -> C -> D 作为您的链表,假设我们必须删除 B。'ptr' 指向 B。

  1. 在 ptr 和 ptr.next 之间交换数据。现在列表是 A -> C -> B -> D
  2. 使 ptr.next 指向 ptr.next.next,使列表 A -> C -> D

对于边缘情况,这可能会失败。如果'ptr'是第一个节点,你只需要将头指向ptr.next。但如果它是最后一个节点,则不能将尾部“向后”移动,因此在这种情况下,您必须遍历列表并跟踪前一个节点。

【讨论】:

    【解决方案2】:

    我知道,如何为 Stack (LIFO) 执行此操作 - 使用 O(1)

    插入/删除

    如果您不介意,该数据会倒退,那么您可以像 first 一样添加最后一项。

    示例: list.insert(1)

    list.insert(2)

    list.insert(3)

    通常会出现在这样的列表中:(1,2,3) 但如果你需要 O(1) 那么它将是这样的:(3,2,1) - 那么最后一项将在位置 1,所以删除将是这样的(红宝石代码)

    def delete
        @head = @head.next 
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 2010-12-29
      • 2020-02-04
      相关资源
      最近更新 更多