什么时候链表优先于列表?

Posted

技术标签:

【中文标题】什么时候链表优先于列表?【英文标题】:When are linked lists preferred over lists? 【发布时间】:2022-01-17 01:50:35 【问题描述】:

我正在使用 Python 学习数据结构和算法。我了解到链表的优点是它没有最大节点数,不像其他语言中的数组。

    由于 Python 会自动为我们调整列表大小,因此优势已被我们抽象掉。

    因此,我一直认为链表的唯一优势是在链表的前面或后面添加一个节点是 O(1),而向列表添加一个元素最终可能是 O( n) 来自 Python,必须调整数组大小并复制每个元素。

但是,我刚刚了解到摊销时间复杂度在今天是一个问题,附加到列表需要摊销 O(1)。因此,将元素添加到列表实际上比将节点添加到链表中要快,因为在链表的前/后以外的任何位置添加节点需要 O(n) 时间复杂度。

那么,在数组/列表上使用链表有什么意义呢?

【问题讨论】:

您并不总是希望追加到列表的末尾。对于涉及在任意点插入或移动项目(例如,将项目从末尾拉出并将其移动到开头)的任务,链表是 O(1),而数组是 O(n)。不同的数据结构在不同的情况下各有优缺点。请注意,这绝不是 Python 特有的! 一般来说,现在很少使用链接列表。现代处理器使用多少缓存和预读,内存局部性非常重要。缓存未命中和页面错误非常昂贵。具有非连续访问模式的链表在实践中表现不佳,即使在纸面上它们的 O(1) 操作应该比数组的 O(n) 更快。 链表有个用例,但它们比动态数组的用例少得多。 作为从业者,你从来没有在实践中使用过 Python 中的链表。理解链表作为一个概念的意义在于,如果您使用不同的非 Python 语言编写代码,您可以识别和使用它们。 @CharlesDuffy deques use linked lists,你是说在实践中不使用双端队列吗? 【参考方案1】:

虽然可以制作一些有用的示例(在人为的情况下,也许您正在使用的工业 ASIC 需要它们),但尤其是链表的简单实现作为一个示例而不是一个实际的结构存在,并且在制造处理器缓存未命中1时通常实际上是一个性能焦油坑,导致性能比它们要差几个数量级出现在纸上

但是,它们是

很好的示例 清晰、完整且最少的指针教学演示 一些更有用、更通用的概念 可以在不移动大量相邻数据的情况下插入中间数据 不必知道数据结构可以使用多长时间 通常不需要立即存储超过活动数据和下一个数据的位置

链接列表在“硬”计算机科学之外也可能有用,它们可以有效地建模,例如,生物过程


备注1。寻找一个精确的例子,但我记得谷歌的一个很好的演示,关于为什么他们不在内部使用一些 stdlib 来防止意外使用链表以及由于性能降低/错误增加而可能导致的其他一些类型

【讨论】:

您能解释一下由/作为链表建模的生物过程是什么意思吗?我有点精通生物网络分析,但我不明白你指的是什么。 @KonradRudolph 哦,我很嫉妒,你肯定比我更清楚,所以它可能不会!尽管如此,我仍然怀疑合成 DNA 的某些用途作为链表是有意义的,尽管在理解和研究它的行为和性能方面可能远远超过在计算模型中如何支持相同结构的表示!跨度>

以上是关于什么时候链表优先于列表?的主要内容,如果未能解决你的问题,请参考以下文章

Java:Effective java学习笔记之 列表优先于数组

Redis数据类型之列表(list)

算法漫游指北(第三篇):数组(列表)链表跳表在python中实现链表

初始化列表

5分钟了解Redis的内部实现快速列表(quicklist)

为啥不使用指针数组来优化链表而使用跳过列表呢?