作为数据容器,vector和list之间的主要区别是什么

xia*_*owl 24 clojure

假设我们需要一个数字列表,有两个定义:

(def vector1 [1 2 3])
(def list2 '(1 2 3))
Run Code Online (Sandbox Code Playgroud)

那么主要的区别是什么?

Paw*_*ski 33

[1 2 3]是一个向量,而是'(1 2 3)一个列表.这两种数据结构有不同的性能特征.

载体提供快速的,其元素索引随机访问(v 34)返回向量的元素v在索引34O(1)的时间.另一方面,修改载体通常更昂贵.

列表易于在头部和/或尾部进行修改(取决于实现),但提供对元素的线性访问:(nth (list 1 2 3 4 5) 3)需要对列表进行顺序扫描.

有关性能权衡的更多信息,您可以谷歌"矢量与列表性能"或类似的东西.

[跟进]

好的,让我们进一步了解一些细节.首先,向量列表是不特定于Clojure的概念.与地图,队列等一起,它们是数据集合的抽象类型.对数据进行操作的算法是根据这些抽象来定义的.矢量列表定义由我上面简要描述的行为(即东西一个矢量,如果它具有的大小,可以通过访问它的元素和在恒定的时间索引等).

与任何其他语言一样,Clojure在提供以这种方式调用的数据结构时希望满足这些期望.如果你看一下in基本实现nthvector,你会看到一个arrayFor方法的调用,它具有O(log 32 N)的复杂性和Java数组中的查找,即O(1).

为什么我们可以说(v 34)实际上是O(1)?因为Java 的log 32的最大值int大约为7.这意味着对矢量的随机访问是事实上的恒定时间.

总之,主要区别vectorslists真正的性能特征.此外,正如Jeremy Heiler指出的那样,在Clojure中,行为存在逻辑上的差异,即在增长收集方面conj.

  • @xiaowl`nth`是一个适用于矢量和列表的函数,它在矢量上提供快速访问. (2认同)
  • 仅供参考,而不是*事实上的恒定时间*,我在Clojure的背景下传统上看到的术语是*有效的恒定时间*. (2认同)

Jer*_*emy 8

列表和向量之间有两个主要区别.

  1. 列表在逻辑上增长在头部,而矢量逻辑上在尾部增长.使用该conj功能时,您可以看到这一点.它将根据给定的集合类型增加集合.虽然您可以在任何一方增加集合,但以这种方式执行此操作是有效的.

  2. 为了检索列表中的第n个项目,需要从头部遍历列表.另一方面,向量不会遍历并返回O(1)中的第n个项目.(它确实是O(log32n),但这是由于集合如何实现为持久集合.)