【问题标题】:Why is removing a node from a doubly-linked list faster than removing a node from a singly-linked list?为什么从双向链表中删除节点比从单链表中删除节点更快?
【发布时间】:2013-10-14 19:05:24
【问题描述】:

我很好奇为什么从双链表中删除节点比单链表快。根据我的讲座,双链表需要 O(1),而单链表需要 O(n)。根据我的思考过程,我认为它们都应该是 O(n),因为您可能必须遍历所有元素,因此这取决于大小。

我知道这将与每个节点都有一个前一个指针和一个指向下一个节点的下一个指针这一事实相关联,我只是无法理解它如何成为 O(1) 意义上的常量操作

【问题讨论】:

标签: pointers data-structures linked-list big-o time-complexity


【解决方案1】:

这部分取决于您如何解释设置。这是两个不同的版本。

版本 1:假设您想从单链表或双链表中删除包含特定值 x 的链表节点,但您不知道它在链表中的哪个位置。在这种情况下,您必须从头开始遍历列表,直到找到要删除的节点。在单链表和双链表中,您都可以在 O(1) 时间内将其删除,因此总体运行时间为 O(n)。也就是说,在单链表中执行删除步骤更加困难,因为您需要更新前一个单元格中的指针(要删除的单元格没有指向该指针),因此您需要将两个指针存储为你这样做。

版本 2:现在假设您获得了一个指向要删除的单元格的指针,并且需要将其删除。在双向链表中,您可以通过使用 next 和 previous 指针来识别要删除的单元格周围的两个单元格,然后重新连接它们以将单元格拼接到列表之外。这需要时间 O(1)。但是单链表呢?要从列表中删除此单元格,您必须更改出现在要删除的单元格之前的单元格的下一个指针,使其不再指向要删除的单元格。不幸的是,您没有指向该单元格的指针,因为该列表只是单链接的。因此,您必须从列表的开头开始,向下遍历节点,然后找到要删除的节点之前的节点。这需要时间 O(n),因此删除步骤的运行时间在最坏情况下是 O(n),而不是 O(1)。 (也就是说,如果您知道 两个 指针 - 您要删除的单元格和它之前的单元格,那么您可以在 O(1) 时间内删除该单元格,因为您不必扫描列表来查找前面的单元格。)

简而言之:如果您提前知道要删除的单元格,则双向链表允许您在 O(1) 时间内将其删除,而单链表则需要 O(n) 时间。如果您事先不知道单元格,那么在这两种情况下都是 O(n)。

希望这会有所帮助!

【讨论】:

  • @arshajii- 我的意思是 O(1),但它是模棱两可的。删除节点的实际步骤是 O(1),但要提前完成 O(n) 工作才能找到它。我刚刚编辑了答案以澄清这一点。
  • 非常感谢!!如果我理解正确,它需要 O(n) (最坏情况),因为在单个链表中,一旦我们找到元素,我们就没有对前一个节点的引用,所以我们不能更改它,接下来将它从列表中删除,所以我们必须再次遍历列表以获取先前的单元格指针
  • @JoshHamet- 如果您知道要删除的节点但不知道之前的节点,您只需要进行遍历。
【解决方案2】:

为了将前一个节点连接到双链表中的后一个节点,不必遍历该列表。你只需点

curr.Prev.Next = curr.Nextcurr.Next.Prev = curr.Prev.

在单链表中,必须遍历链表才能找到上一个节点。在未排序的列表中遍历可以是 O(n)。

【讨论】:

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