我继续听取人们和文档的说法,std :: deque是一个随机访问,就像std :: vector一样,并且像链接列表一样是时间插入和删除。另外,与向量不同,std :: deque可以在开始和结束时以恒定时间插入元素。我不确定标准是否指定了std :: deque的特定实现,但它应该代表双端队列,并且很可能实现结合了与指针链接在一起的类似矢量的分配缓冲区。一个关键的区别是元素不像std :: vector那样连续。
鉴于它们不是连续的,当人们说它们像矢量一样是随机访问时,我认为它们是以“摊销”的意义而不是现实中的载体?这是因为向量只涉及一个偏移地址,保证每次都能进行真正的恒定时间访问,而双端队列必须计算所请求元素在序列中的距离,并计算沿着它的链接缓冲区数量。去找到那个特定的元素。
同样,链接列表中的插入仅涉及断开一个链接并设置另一个链接,而在双端队列(不是最后一个或第一个成员)中的插入必须至少在所有成员之后移动插入点至少对于那个特定的链接缓冲区一个地方。例如,如果一个链接缓冲区有10个成员并且你碰巧在该特定缓冲区的开头插入,那么它必须至少移动10个成员(如果是超过缓冲容量并且不得不重新分配。)
我有兴趣了解这一点,因为我想实现一个队列,而在标准库中,std :: queue就是他们所谓的容器适配器,这意味着我们并没有确切知道它是什么容器类型,只要因为它以队列的方式运行。我认为它通常是std :: deque或std :: list的一种包装器。鉴于我只对先入先出类型的东西的简单功能感兴趣,我几乎可以肯定链接列表在插入队列和弹出结束时会更快。所以我很想明确选择那个而不是std :: queue。
另外,我知道链接列表对迭代的缓存不太友好,但我们正在比较一个链表而不是一个矢量而是一个双端队列,据我所知,必须做一个相当大的事情。保留记录的数量,以便知道在迭代过程中它在多远和哪个特定缓冲区中。
编辑:我刚刚对另一个感兴趣的问题发表评论:
“我见过的C ++实现使用了一个指针数组 固定大小的数组。这实际上意味着push_front和 push_back不是真正的常数,而是智能增长 因此,你仍然可以按常数摊销,所以O(1)不是 如此错误,在实践中它比矢量更快,因为你是 交换单个指针而不是整个对象(和更少的指针 比对象)。 - Matthieu M. Jun 9 '11“
答案 0 :(得分:1)
它是随机访问,但常量时间插入和删除仅适用于序列的开头和结尾,在它的中间是O(n)。
它是O(1)来访问一个项目,但它不像O(1)那样有效。它将采用相同数量的计算来确定项目在双端队列中的位置,而不管其位置如何,即使无论在双端队列中有多少项目。将其与列表中的位置进行比较,找到第n个项目,你必须走n-1个前面的项目。