矢量是链表的特例吗?

时间:2011-01-15 14:20:40

标签: c++ stl vector linked-list

在谈到STL时,我有几个同学告诉我“向量是链接列表”。

我有另一个人认为如果用迭代器调用erase()方法,它会破坏向量,因为它是一个链表。

他们也倾向于不明白为什么我总是认为向量是连续的,就像任何其他数组一样,并且似乎不理解随机访问的含义。矢量是否像常规数组一样严格连续,或者只是最连续? (例如,如果整个数组不适合,它将分配几个连续的段。)

4 个答案:

答案 0 :(得分:26)

我很遗憾地说你的同学完全错了。如果你的同学可以诚实地说“向量是链接列表”,那么你需要尊重地告诉他们他们需要拿起a good C++ book(或任何体面的计算机科学书籍)并阅读它。或者甚至是vectorslists的维基百科文章。 (另请参阅dynamic arrayslinked lists的文章。)


向量(如std::vector不是链接列表。 (请注意,std::vector并非来自std::list)。虽然它们都可以存储数据集合,但是矢量如何与链接列表完成不同。因此,它们在不同情况下具有不同的性能特征。

例如,插入是链接列表上的常量时间操作,而如果它插入到除结尾之外的某个位置,则它是向量的线性时间操作。 (但是,如果在向量的末尾插入,则摊销常量时间。)

C ++中的std::vector必需与C ++标准连续:

  

23.2.4 / 1课程模板vector

     

vector是一种支持随机访问迭代器的序列。此外,它支持(摊销)最后的恒定时间插入和擦除操作;在中间插入和擦除需要线性时间。存储管理是自动处理的,但可以提供提示以提高效率。 vector的元素是连续存储的,这意味着如果vvector<T, Allocator>,其中Tbool以外的某种类型},然后它服从所有&v[n] == &v[0] + n的身份0 <= n < v.size()

将其与std::list

进行比较
  

23.2.2 / 1班级模板list

     

list是一种支持双向迭代器的序列,允许在序列中的任何位置进行恒定时间插入和擦除操作,并自动处理存储管理。与矢量(23.2.4)和deques(23.2.1)不同,不支持对列表元素的快速随机访问,但许多算法无论如何都只需要顺序访问。

显然,C ++标准规定向量和列表是两个不同的容器,它们以不同的方式做事。

你不能通过简单地用有效的迭代器调用erase()来“破坏”一个向量(至少不是故意的)。这会使std::vector变得毫无用处,因为它的存在就是为你管理记忆!

答案 1 :(得分:8)

vector会将的所有存储在一个地方。 vector甚至不像链接列表那样远。事实上,如果我必须选择两个彼此最不相同的数据结构,那么它将是vectorlist。 “最多是连续的”是deque的运作方式。

载体:

  1. 保证所有元素的连续存储 - 将复制或移动元素。
  2. O(1)访问时间。
  3. O(n)用于插入或移除。
  4. 迭代器在插入或删除任何元素时失效。
  5. 列表:

    1. 根本没有连续存储 - 永远不会复制或移动元素。
    2. O(n)访问时间 - 加上你将要获得的所有令人讨厌的缓存未命中。
    3. O(1)插入或移除。
    4. 只要未删除该特定元素,迭代器就会有效。
    5. 如您所见,它们在每个数据结构用例中的行为都不同。

答案 2 :(得分:2)

根据定义,vector是连续的内存块,如C数组。见:http://en.wikipedia.org/wiki/Vector_(C%2B%2B

  

矢量允许随机访问;那是,   向量的元素可能是   以与...相同的方式引用   数组元素(通过数组索引)。   链接列表和集合,另一方面   手,不支持随机访问或   指针算术。

答案 3 :(得分:0)

向量不是链接链表,它们提供随机访问,并且与数组一样是连续的。为了实现这一点,他们重新分配内存。

List旨在允许快速插入和删除,同时不会使除任何引用或迭代器失效 删除元素的那些。