如果链表比数组具有许多功能优势,那么数组相对于链表有什么优势?

时间:2017-04-11 15:00:42

标签: c++ arrays linked-list

我看到的链接列表优势是列表之间的无限动态空间和自动更新功能。数组缺少链表的许多有用功能。那么为什么在某些情况下使用数组而不是链表呢?

2 个答案:

答案 0 :(得分:4)

数组具有O(1)速度的随机访问。数组可以在编译时确定长度。数组中的数据是连续的,这意味着它对CPU内存缓存非常友好。数组不需要花费在开销上的每个元素,比如下一个/上一个指针,所以更紧凑。

链接列表是基于节点的数据结构。没有极大的努力,他们非常不友好。它们很笨重 - 字节列表可能有1600%以上的容器开销,超过等效数组的17倍。

std::vector是一个动态数组。实际上,在实际找到要使用的元素的成本中,std::vector几乎在您可以分析的每种情况下都会使std::list的裤子超过@M. Ihsan。有一些例外,主要涉及内存中的数据稳定性和迭代器持久性。

答案 1 :(得分:1)

因为没有免费的午餐。

通常,如果数据结构比另一个更强大,您将不得不以某种方式支付额外的功率。有时你不愿意支付这个价格。

至于列表,你是正确的,就功能而言,它们比数组更好:

  • 您可以有效地在列表中的任何位置插入和删除元素,而无需复制
  • 周围的现有元素
  • 列表可以无限增长。如果你想要一个不断增长的数组,你基本上必须将所有现有元素复制到更大的数组,然后扔掉旧数组。
  • 您无需复制即可高效move elements from one list to another

阵列不能做到这一点!

但是因为数组不必支持这些功能,所以他们也不必为列出实现所带来的额外复杂性付出代价:

  • 列表必须分别分配每个元素。这意味着实施的更复杂的生命周期管理以及对newdelete的大量调用。你不会在小程序中注意到这一点,但这些调用非常慢,更糟糕的是,你使用它们的速度越慢,它们就越慢。
  • 因为元素是独立分配的,所以它们可能最终分散在整个内存中。这对于缓存很不利,因为如果所有数据在内存中都很接近,则缓存最有效。在现代桌面计算机上,这会对性能产生巨大影响,因为访问内存比访问缓存要慢得多。它实际上是如此之大,通常情况下,在复制元素方面你需要做的额外工作仍然比处理列表的错误缓存行为更便宜。
  • 阵列允许随机访问。这意味着我总是可以直接从索引中找到数组的任何元素。对于列表,我需要遍历列表,因此如果我的元素进一步返回列表,则需要更长时间才能到达列表。此外,较大的列表比较小的列表需要更长的遍历。如果我经常使用需要快速执行一系列随机访问的算法,那么使用数组可以获得很大的性能。二进制搜索就是一个明显的例子。

所以,正如你所看到的,有一个权衡。增加的灵活性是很好的,但它的成本可能会让你感到困惑,这取决于你想对数据结构做什么。顺便说一句,所有数据结构都是如此。例如,树在某种程度上解决了列表的慢查找问题,但与列表和数组相比,它们还有其他缺点。作为程序员,您必须熟悉不同数据结构的不同优点和缺点,这样才能为每个问题选择合适的优势和缺点。