链接列表与矢量

时间:2013-09-26 22:49:04

标签: data-structures vector linked-list

在过去的几天里,我一直在准备我的第一次电话采访,以进行软件开发工作。在研究问题时,我提出了this article.

在我开始这段经历之前,每件事都很棒,

  

“您何时使用链接列表与向量?”

根据经验和研究,这些是两种截然不同的数据结构,链表是动态数组,矢量是空间中的2d点。我可以在两者之间看到的唯一关联是,如果您使用向量作为链接列表,请说myVector(my value, pointer to neighbor)

思想?

5 个答案:

答案 0 :(得分:42)

Vector是dynamic arrays的另一个名称。它是dynamic array data structure in C++使用的名称。如果您有Java经验,可以使用名称ArrayList来了解它们。 (Java也有一个名为Vector的旧集合类,由于它的设计方式存在问题,现在还没有使用过。)

向量适用于随机读取访问以及后面的插入和删除(采用分摊的常量时间),但对于前面或任何其他位置的插入和删除(线性时间,因为必须移动项目)不利。向量通常在内存中连续布局,因此遍历一个是有效的,因为CPU内存缓存得到有效使用。

另一方面,

Linked lists适用于插入和删除前面或后面的项目(常量时间),但对其他内容不是特别好:例如,删除中间任意索引处的项目列表需要线性时间,因为您必须首先找到节点。另一方面,一旦找到特定节点,您可以将其删除或在常量时间之后插入新项目,这是您无法使用向量进行的。链接列表的实现也非常简单,这使它们成为一种流行的数据结构。

答案 1 :(得分:4)

我知道这个问题有点晚了,但这是Bjarne Stroustrup(C ++的发明者)关于为什么要避免链接列表与现代硬件的非常有见地的视频。 https://www.youtube.com/watch?v=YQs6IC-vgmo 通过今天计算机上的快速内存分配,可以更快地创建更新项目的矢量副本。

答案 2 :(得分:2)

我不喜欢这里的头号答案所以我想我会分享一些来自微软的Herb Sutter对此进行的实际研究。测试的结果是一个容器中有多达10万件物品,但也声称它将继续在甚至五十万个实体中执行一个链表。除非您计划拥有数百万实体的容器,否则动态容器的默认容器成为向量。我或多或少总结了什么他说,但也会链接底部的参考文献:

“[即使]你预先分配链接列表中的节点,这会给你一半的性能,但它仍然比[矢量]更糟。为什么?首先它是更多的空间 - 每个元素的开销(原因之一) - 链接列表中涉及的前向和后向指针 - 但也(更重要的是)访问顺序。链表必须遍历以查找插入点,执行所有此指针追逐,矢量正在做同样的事情,但实际发生的是预取程序是那么快。使用在内存中有效映射的数据执行线性遍历(分配和使用,例如,指针向量在定义和布局中,它几乎在每个场景中都优于链表。“

https://youtu.be/TJHgp1ugKGM?t=2948

答案 3 :(得分:1)

使用向量,除非“数据大小很大”或“强有力的安全保证是必不可少的”。

数据量很大 : - 插入中间的向量需要线性时间(因为需要随机播放),但其他是常量时间操作(如遍历到第n个节点)。因此,如果数据大小很小,则没有太多开销。

根据“C ++编码标准书Andrei Alexandrescu和Herb Sutter”

“对小列表使用向量几乎总是优于使用列表。即使在序列中间插入是向量的线性时间操作和列表的常量操作,向量通常优于列表时的列表因为它具有更好的常数因子而相对较小,并且在数据大小变大之前,列表的Big-Oh优势不会发挥作用。“

强大的安全保障 清单提供强大的安全保证。 http://www.cplusplus.com/reference/list/list/insert/

答案 4 :(得分:1)

作为对链接列表中插入和删除的大O时间的修正,如果你有一个指针来保存当前元素的位置,以及用于在列表中移动它的方法,(如{{1} },.moveToStart().moveToEnd()等),您可以在固定时间内删除和插入。