Python 链表的时间复杂性

Python 链表的时间复杂性,python,Python,查看链接列表如何找到彼此的可视化。我知道一个节点指向另一个节点,但它必须找到该节点,因为每个节点在物理上不一定跟在前一个节点后面 记忆这是否意味着在遍历链表时,它可能必须跳过其他节点才能找到序列中的下一个节点? 如果在这种情况下,当定位元素时0(n)是不正确的。我知道这是正确的,但我正试图想象上述情况 提前感谢链接列表如下所示: head | v +--+-+ +--+-+ +--+-+ +--+-+ | 1|*|--->| 2|*

查看链接列表如何找到彼此的可视化。我知道一个节点指向另一个节点,但它必须找到该节点,因为每个节点在物理上不一定跟在前一个节点后面 记忆这是否意味着在遍历链表时,它可能必须跳过其他节点才能找到序列中的下一个节点? 如果在这种情况下,当定位元素时0(n)是不正确的。我知道这是正确的,但我正试图想象上述情况


提前感谢

链接列表如下所示:

    head
     |
     v
   +--+-+    +--+-+    +--+-+    +--+-+
   | 1|*|--->| 2|*|--->| 3|*|--->| 4|/|
   +--+-+    +--+-+    +--+-+    +--+-+
它表示以下代码:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None


head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.next.next.next = Node(4)
如果您只有
head
开始,那么到达列表中的任意节点必然需要O(n)个时间,因为对该节点的唯一引用存储在前一个节点中,而前一个节点只能从其前一个节点访问,等等。链表中没有“跳过”

存在存储多个链接的数据结构,可以加快访问速度,但代价是增加所需空间的数量



O(n)并不意味着对于某些常数c,每个操作都需要cn步;这意味着在最坏的情况下,至少有一个操作需要cn步。

在链表的每个元素中基本上都有一个元组(value,pointerToMemoryPosition)——其中pointerToMemoryPosition基本上是系统的内在值

通过让直接指针指向下一个节点而不需要查找它,您可以跳转到O(1)中的正确位置。内存中的位置是0xAAAA还是0xCFA11并不重要。你总是能够直接跳到正确的位置

如果你去成功的接班人那里,你将不得不做两次跳跃。但是您不必遍历这两个元素之间的内存区域


希望它能回答您的问题。

内存是随机访问的;给定对对象的引用,可以在O(1)时间内看到对象本身。但是,首先到达任何给定的引用都需要O(n)个时间,因为您必须首先遍历前面的每个引用,而(n)只是指最坏的情况。例如,如果一个链表有100个元素,它将是0(100)?@Continuit O(100)没有任何意义。这从根本上误解了Big Oh表示法所描述的内容,它描述了算法的缩放是的,但n指的是它将采取的最大操作量,因此它确实有意义。当搜索链接列表时,您可能会在检查的第一个节点上找到匹配项,或者在找到最后一个节点之前可能无法找到匹配项。您需要检查的平均节点数为n/2,但在Big-O计算中忽略了
/2
部分。这是让我感到困惑的参考部分。我怎么能想象呢?@想象什么?我认为对你来说,重要的是要理解,在具有随机存取存储器的现代计算机中,数据的有效读取时间与物理位置无关。回到过去,事实并非如此,但现在是。@juanpa.arrivillaga我认为这与此无关。关键是,在查看下一个到最后一个节点之前,您甚至不知道列表中最后一个节点的地址,在查看下一个到下一个到最后一个节点之前,您也不知道它的地址,等等。@chepner如果它是一个双端链接列表。第一个节点是否包含最后一个节点的信息?不清楚“双端”链表是什么意思,但常见的做法是在列表中存储除第一个节点外的最后一个节点的一个额外引用。这并不能加快大多数操作的速度(您仍然需要从列表的开头走到中间的某个位置),但它会使向列表中追加一个项成为一个O(1)操作,而不是O(n),因为您已经从末尾的引用开始,因此,计算机知道内存中的每个位置,目标只是找到正确的位置。所以一旦它知道位置是“0xAAAAA”,那么它就需要O(1)?完全正确。