【问题标题】:How is sort for std::deque implemented?std::deque 的排序是如何实现的?
【发布时间】:2014-08-03 15:57:35
【问题描述】:

到目前为止,我还没有了解std::deque 是如何在后台实现的,并且发现它类似于指向 n 字节数组的指针数组,数据实际存储在其中。所以现在我有几个与双端队列相关的问题。

一张描述我目前对其结构了解的图片:

问题是:

  1. 当正在执行push_front 操作并且数据块 0 中没有可用空间时,会在堆上分配一个新数据块,并将指向此新分配内存的指针插入到“映射”数组中,如在普通数组中——在 O(number_of_blocks) 时间内,是吗?

  2. 如何分类这头野兽?无法想象比将所有数据复制到数组中更好的方法,对其进行排序,然后将其放回原处。但是这种方法需要 O(n) 辅助内存……但是! std::sortstd::vectorstd::deque 的排序提供了类似的接口。不同数据结构的不同算法是如何实现的?使用模板专业化?如果是这样,为什么不能使用std::sortstd::list 进行排序? 或者,也许std::sort 不关心这个容器的内部结构,只使用迭代器和方法,它们在std::vectorstd::deque 中是相似的(比如operator[]size() 等)?这个想法听起来很合理,也是对“为什么不能std::sort 排序std::list?”的回答。变得明显。

  3. 如何选择数据块的大小?您会说“它取决于实现”,但请详细说明不同的实现和解决方案背后的动机。

这里需要澄清。 谢谢。

【问题讨论】:

  • 它们背后的数学无法承受,std::deque 具有随机访问迭代器,因此任何就地排序算法都能够使用该功能对数据进行排序,而不需要 O(N)额外的存储空间。 std::list 不提供随机访问迭代,因此不是 std::sort-able。 (但是,std::list::sort-able)。请参阅the documentation of std::sort类型要求部分。
  • 您缺少 STL 的容器 算法方案。排序与任何其他具有随机访问迭代器的容器相同。
  • std::sort 适用于任何随机访问迭代器。 std::vectorstd::deque 都提供随机访问迭代器,但 std::list 不提供。没有(必然)任何模板专业化魔法或任何东西,因为std::sort 通过交换提供的范围内的元素来工作;这不需要大量额外的存储空间,也不需要容器/范围/迭代器背后的任何特殊知识。

标签: c++ sorting vector stl deque


【解决方案1】:

要回答您的第一个问题,是的,这就是它的工作原理。可以注意到,这种方法可以扩展到多层次的层次结构。但实际的实现通常坚持两级结构,正如您的图片所示。

对于第二个问题,如果您谈论的是std::sort,那么std::sort 可以在不了解实际容器机制的情况下工作。如果适用于一系列随机访问迭代器。由于std::deque 的迭代器是随机访问迭代器,所以std::sort 可以应用于std::deque。事实上,人们可以争辩说,随机访问这种数据结构的元素是相当有效的。它不如向量中的随机访问有效,但在std::sort 的上下文中仍然很有效。

您不能将std::sortstd::list 一起使用,因为std::list 的迭代器不是随机访问迭代器。如果您愿意,您可以为std::list 实现自己的简单(慢)版本的随机访问迭代器。您将能够将std::sort 应用于一系列此类迭代器,从而将std::liststd::sort 排序。但由于显而易见的原因,它的效率会非常低。

std::deque 的情况下,随机访问迭代器的效率绰绰有余。

我不准备回答第三个问题。事实上,我不会惊讶地发现这些尺寸是根据大量实验根据经验选择的。而且,当然,可能没有“一刀切”的解决方案。

【讨论】:

  • 关于他的第二个问题:重要的一点是std::sort 交换实际数据,无论它位于何处,因此它与容器的底层结构完全无关。
猜你喜欢
  • 2015-01-31
  • 2017-10-27
  • 2019-10-12
  • 2014-06-06
  • 2013-04-10
  • 2013-11-01
  • 1970-01-01
  • 2020-04-26
  • 2010-11-30
相关资源
最近更新 更多