Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么std::deque子阵列大小是固定的?_C++_Algorithm_C++11_Time Complexity_Deque - Fatal编程技术网

C++ 为什么std::deque子阵列大小是固定的?

C++ 为什么std::deque子阵列大小是固定的?,c++,algorithm,c++11,time-complexity,deque,C++,Algorithm,C++11,Time Complexity,Deque,背景 std::deque使用子数组存储其元素。它有一个额外的簿记数据结构来跟踪它的子数组。这样,与std::vector相比,std::deque从后面增长得更快(O(1)比摊销O(1)),从前面增长得更快(O(1)比O(n))。这是因为std::deque可以在任意一端添加子数组,只需修改其簿记数据结构 问题 我不明白的是,为什么子阵列的大小是固定的,如下所述: 典型的实现使用一系列单独分配的固定大小的数组 没有固定大小的子阵列有很多优点。例如,由于子阵列是固定的,中间的任何插入都必须是O

背景

std::deque
使用子数组存储其元素。它有一个额外的簿记数据结构来跟踪它的子数组。这样,与
std::vector
相比,
std::deque
从后面增长得更快(O(1)比摊销O(1)),从前面增长得更快(O(1)比O(n))。这是因为
std::deque
可以在任意一端添加子数组,只需修改其簿记数据结构


问题

我不明白的是,为什么子阵列的大小是固定的,如下所述:

典型的实现使用一系列单独分配的固定大小的数组

没有固定大小的子阵列有很多优点。例如,由于子阵列是固定的,中间的任何插入都必须是O(n)复杂度,其中n是到最接近端的元素的数目。然而,如果子阵列是自由增长的,中间的插入将是O(k),其中k是子数组中的元素的数目,这是非常快的,特别是如果<代码> STD::DeQu/Cuth>有很多子数组。从中间删除也是一样的

这是因为
std::deque
想要保持其子阵列的平衡吗?如果子阵列太大/太小,可以通过启用子阵列拆分或合并来轻松缓解这一问题。复杂度仅为O(k),其中k是最大子阵列的大小。(或最小子阵列及其较小邻居的组合大小)

是因为固定大小的子数组使得随机迭代更快吗?例如,如果需要第n个元素,则必须遍历簿记数据结构并添加前面所有子数组的大小,使复杂性为O(k),其中k是簿记的大小 数据结构。但这也不是什么大不了的事,因为
std::deque
被宣传为具有更好缓存的双链接列表


EDIT:
std::deque
只是链表实现和数组实现之间的中间人。我想我的问题已经失去了它原来的意义,只是建议它应该更像一个链表,而不是一个向量

我不明白的是为什么子阵列的大小是固定的

因为这允许标准要求的恒定复杂性随机访问,正如评论中指出的那样


但这并不是什么大问题

我不同意,标准委员会大概也不同意

由于
std::deque
被广告为双链接列表


它不是这样做的。

如果我问你什么是
2*23
,你有多难思考,现在比较一下如果我问你什么是
13+10+19+4
,你有多难思考。而且我不同意你的观点,对于固定大小的桶,插入顺序是O(n)。这不是文件所说的,也不一定是真的。固定大小的buckets比随机调整buckets大小的buckets更容易插入“中间”(您确实需要定义其含义),而不是插入两端。而且,在中间插入是O(n),因为你必须将所有值从插入点移到DeQo的末端,对于所有的子序列都不能是O(n),它更像O(k),其中k是每个桶的大小。我认为你把deque和链表搞混了。如果你有一个大小为133的deque,你想到达包含索引97的bucket;如果你知道每个bucket的大小都是20,那么要达到包含97的bucket,你只需将97除以20,得到4,然后在这个bucket上,你可以做(97-4*20)得到17,这是你要寻找的索引。总之O(1)。现在插入该bucket,如果bucket只是一个数组,那么您只需将其中的元素替换为新的元素。总计0(1)。如果bucket是链表,那么它可能会更大一点,而且扩展deque会产生一些额外的成本,我已经解决了这个问题。我所看到的
std::deque
的大多数用例都涉及插入和删除。我不认为随机访问的减少是至关重要的。@PhotometricStereo,我认为问题在于你是从链表的角度来看deque的,然而,它更像是矢量的竞争者,它不是性能的“下降”,而是渐进复杂性的变化。要求是O(1)随机访问,因此更改为O(k)是不符合要求的。如果O(k~n)访问足够-您可以首先使用列表。std:deque保证摊销固定时间索引查找。参见[sequence.reqmts]中的要求表,当前参考26.2.3/14:“表88列出了为某些类型的序列容器而不是其他类型的容器提供的操作。实施应为“容器”中显示的所有容器类型提供这些操作。”列,并应予以实施,以便采用摊余固定时间。”