单链表和双链表中节点删除的时间复杂度

发布于 2024-08-14 02:50:44 字数 47 浏览 2 评论 0原文

为什么双链表中节点删除的时间复杂度(O(1))比单链表中节点删除(O(n))快?

Why is the time complexity of node deletion in doubly linked lists (O(1)) faster than node deletion in singly linked lists (O(n))?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

清眉祭 2024-08-21 02:50:44

该问题假设要删除的节点是已知的并且指向该节点的指针可用。

为了删除一个节点并将前一个和下一个节点连接在一起,您需要知道它们的指针。在双向链表中,要删除的节点中的两个指针都可用。在这种情况下时间复杂度是恒定的,即O(1)。

而在单链表中,指向前一个节点的指针是未知的,只能通过从头开始遍历链表直到到达具有指向要删除的节点的下一个节点指针的节点来找到。这种情况下的时间复杂度是O(n)。

如果仅通过值知道要删除的节点,则必须搜索列表,并且无论是单链表还是双链表,时间复杂度都变为 O(n)。

The problem assumes that the node to be deleted is known and a pointer to that node is available.

In order to delete a node and connect the previous and the next node together, you need to know their pointers. In a doubly-linked list, both pointers are available in the node that is to be deleted. The time complexity is constant in this case, i.e., O(1).

Whereas in a singly-linked list, the pointer to the previous node is unknown and can be found only by traversing the list from head until it reaches the node that has a next node pointer to the node that is to be deleted. The time complexity in this case is O(n).

In cases where the node to be deleted is known only by value, the list has to be searched and the time complexity becomes O(n) in both singly- and doubly-linked lists.

幸福不弃 2024-08-21 02:50:44

实际上单链表的删除也可以在 O(1) 内实现。

给定一个具有以下状态的单链表:

SinglyLinkedList:
   Node 1 -> Node 2
   Node 2 -> Node 3
   Node 3 -> Node 4
   Node 4 -> None

   Head = Node 1

我们可以通过以下方式实现删除节点 2

Node 2 Value <- Node 3 Value
Node 2 -> Node 4

这里我们将节点 2 的值替换为其下一个节点的值(Node 3) 并将其下一个值指针设置为 Node 3 (Node 4) 的下一个值指针,从而有效地跳过现在的“重复”节点 3。因此不需要遍历。

Actually deletion in singly linked lists can also be implemented in O(1).

Given a singly linked list with the following state:

SinglyLinkedList:
   Node 1 -> Node 2
   Node 2 -> Node 3
   Node 3 -> Node 4
   Node 4 -> None

   Head = Node 1

We can implement delete Node 2 in such a way:

Node 2 Value <- Node 3 Value
Node 2 -> Node 4

Here we replace the value of Node 2 with the value of its next node (Node 3) and set its next value pointer to the next value pointer of Node 3 (Node 4), skipping over the now effectively "duplicate" Node 3. Thus no traversal needed.

青朷 2024-08-21 02:50:44

因为你无法回头看...

Because you can't look backwards...

夜声 2024-08-21 02:50:44

在已知位置插入和删除的时间复杂度为 O(1)。然而,找到该位置的时间复杂度为 O(n),除非它是列表的头或尾。

当我们谈论插入和删除复杂性时,我们通常假设我们已经知道这将发生在哪里。

Insertion and deletion at a known position is O(1). However, finding that position is O(n), unless it is the head or tail of the list.

When we talk about insertion and deletion complexity, we generally assume we already know where that's going to occur.

黑寡妇 2024-08-21 02:50:44

它与修复要删除的节点之前的节点中的下一个指针的复杂性有关。

It has to do with the complexity of fixing up the next pointer in the node previous to the one you're deleting.

梦年海沫深 2024-08-21 02:50:44

除非要删除的元素是头节点,否则我们需要遍历到要删除的元素之前的节点。因此,在最坏的情况下,即当我们需要删除最后一个节点时,指针必须一直走到倒数第二个节点,从而遍历 (n-1) 个位置,这给了我们 O(n) 的时间复杂度。

Unless the element to be deleted is the head(or first) node, we need to traverse to the node before the one to be deleted. Hence, in worst case, i.e., when we need to delete the last node, the pointer has to go all the way to the second last node thereby traversing (n-1) positions, which gives us a time complexity of O(n).

另类 2024-08-21 02:50:44

我不认为它的 O(1) 除非你知道地址
必须删除的节点.....您不循环到达必须从头删除的节点吗???

如果您拥有必须删除的节点的地址,那么它的复杂度是 O(1),因为您拥有它的上一个节点链接和下一个节点链接。
由于您拥有所有必要的链接,只需通过重新排列链接将“感兴趣的节点”从列表中删除,然后 free() 它即可。

但是在单个链表中,您必须从头开始遍历才能获取它的上一个和下一个地址,无论您是否有要删除的节点的地址或节点位置(如第 1 个、第 2 个、第 10 个等), .) 待删除。

I don't think Its O(1) unless you know the address of the
node whichh has to be deleted ..... Don't you loop to reach the node which has to be deleted from head ????

It is O(1) provided you have the address of the node which has to be deleted because you have it's prev node link and next node link .
As you have all the necessary links available just make the "node of interest " out of the list by re arranging the links and then free() it .

But in a single linked list you have to traverse from head to get it's previous and next address doesn't matter whether you have the address to f the node to be deleted or the node position ( as in 1st ,2nd ,10th etc.,.) To be deleted .

猫七 2024-08-21 02:50:44

假设有一个从 1 到 10 的链表,并且您必须删除给定位置的节点 5。

1 -> 2 -> 3 -> 4 -> 5-> 6-> 7-> 8 -> 9 -> 10

您必须将 4 的下一个指针连接到 6 才能删除 5。

  1. 双向链表
    您可以使用 5 上的前一个指针转到 4。然后您可以执行
4->next = 5->next;

Node* temp = givenNode->prev;
temp->next = givenNode->next;

时间复杂度 = O(1)

  1. 单链表
    由于单链表中没有前一个指针,因此无法向后移动,因此必须从头开始遍历列表
Node* temp = head;
while(temp->next != givenNode)
{
  temp = temp->next;
}
temp->next = givenNode->next;

时间复杂度 = O(N)

Suppose there is a linked list from 1 to 10 and you have to delete node 5 whose location is given to you.

1 -> 2 -> 3 -> 4 -> 5-> 6-> 7-> 8 -> 9 -> 10

You will have to connect the next pointer of 4 to 6 in order to delete 5.

  1. Doubly Linked list
    You can use the previous pointer on 5 to go to 4. Then you can do
4->next = 5->next;

or

Node* temp = givenNode->prev;
temp->next = givenNode->next;

Time Complexity = O(1)

  1. singly Linked List
    Since you don't have a previous pointer in Singly linked list you cant go backwards so you will have to traverse the list from head
Node* temp = head;
while(temp->next != givenNode)
{
  temp = temp->next;
}
temp->next = givenNode->next;

Time Complexity = O(N)

谎言月老 2024-08-21 02:50:44

在LRU缓存设计中,双向链表中的删除需要O(1)时间。 LRU缓存是通过哈希图和双向链表实现的。在双向链表中,我们存储值,它的哈希映射存储链表节点的指针。

输入图片这里的描述

如果缓存命中,我们必须将元素移动到列表的前面。如果节点位于双向链表中间的某个位置,由于我们将指针保留在哈希映射中并且我们在 O(1) 时间内检索,我们可以通过将

  next_temp=retrieved_node.next
  prev_temp=retrieved_node.prev

指针设置为 None 来

  retrieved_node.next=None
  retrieved_node.prev=None

删除它,然后您可以重新连接丢失的节点链表的一部分

 prev_temp.next=next_temp

In LRU cache design, deletion in doubly linked list takes O(1) time. LRU cache is implemented with hash map and doubly linked list. In the doubly linked list, we store the values and it hash maps we store the pointers of linked list nodes.

enter image description here

In case of a cache hit, we have to move the element to the front of the list. If the node is somewhere in the middle of doubly linked list, since we keep the pointers in the hash map and we retrieved in O(1) time, we can delete it by

  next_temp=retrieved_node.next
  prev_temp=retrieved_node.prev

then set the pointers to None

  retrieved_node.next=None
  retrieved_node.prev=None

and then you can reconnect the missing parts of the linked list

 prev_temp.next=next_temp
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文