【发布时间】:2019-06-02 12:28:13
【问题描述】:
我被告知,一般来说,从链表中添加和删除往往会更好,因为不必移动内存来容纳新元素。我不确定这是否真的适用于添加/删除可以在列表中的任何位置。
如果我是正确的,链表会这样操作;它会在O(n)时间内找到需要添加/删除的节点的位置,然后在O(1)内添加/删除节点,总时间为O(n)。
在一个数组中;由于随机存取内存,它会在 O(1) 时间内找到需要添加/删除的节点的位置,然后在 O(n) 时间内添加/删除节点,因为可能需要移动所有数据数组(假设删除意味着将所有节点移回 1)。从而给出O(n)的整体操作时间
由此看来,两者似乎都没有明显的优势。如果我查看平均情况,则链表平均会执行 n/2 次操作,因为节点平均位于列表的中间。
对于数组,出于类似原因,删除也需要平均 n/2 次操作,而如果需要移动所有数据以容纳额外元素,则添加将需要 n/2 次操作,如果有足够的空间并且需要将数据向上移动 1 个空间。这是否会给出 2*n/3 的平均值,这可能是为什么链表会更好的原因吗?
【问题讨论】:
-
如果您无权访问节点本身,则两者都是 O(n)。链表需要 O(n) 来寻找节点,而数组需要 O(n) 来将剩余元素向左移动。
-
@WillemVanOnsem 所以两者都不是更好,因为我们不能再做任何假设了?
-
如果索引与列表的大小相比通常较小,则链表会更好,如果索引更多位于列表末尾,则数组更好。
-
@WillemVanOnsem 嗯,这是一个额外的假设。似乎平均而言,数组的下界为 n/2,上界为 3n/4,而链表的平均值始终为 n/2。最好的情况是 O(1),所以这不太有用。
-
您的里程会有所不同,但请记住,数组比链表对缓存更友好。 Herb Sutter 做了一个精彩的演讲,他谈到了这个:youtube.com/watch?v=TJHgp1ugKGM(如果你想了解好东西,请跳到大约 29:27)。
标签: arrays algorithm linked-list