【发布时间】:2011-12-01 01:19:36
【问题描述】:
由于几天前this 的问题,有一些事情一直困扰着我关于std::deque::push_back/push_front 与实际std::deque 实现的复杂性要求。
上一个问题的结果是要求这些操作具有O(1) 最坏情况复杂度。我验证了c++11中确实是这种情况:
来自 23.3.3.4 的双端队列修饰符,指的是插入、推送/放置前/后
复杂度:复杂度与插入的元素数加上 到双端队列的开头和结尾的距离较小。插入单个 双端队列开头或结尾的元素总是花费恒定的时间,并且 导致对 T 的构造函数的一次调用。
这与索引的O(1) 复杂性要求相结合,通过operator[] 等。
问题在于实施并未严格满足这些要求。
就msvc 和gcc 而言,std::deque 实现是一个块数据结构,由指向(固定大小)块的指针的动态数组组成,其中每个块存储许多数据元素。
在最坏的情况下,push_back/front etc 可能需要分配一个额外的块(这很好 - 固定大小分配是 O(1)),但它也可能需要调整块指针的动态数组的大小 - 这是不好,因为这是O(m),其中m 是块数,最终是O(n)。
显然这仍然是摊销O(1) 的复杂性,因为通常m << n 在实践中会很快。但似乎一致性有问题?
另外一点,我看不出如何设计一个严格满足O(1) 复杂性的push_back/front etc 和operator[] 的数据结构。你可以有一个块指针的链表,但这并没有给你想要的 operator[] 行为。真的可以做到吗?
【问题讨论】:
-
相关(但也没有真正回答):stackoverflow.com/questions/6292332/…
-
@NateKohl:是的,这个问题的答案似乎证实了你不能严格满足所有的复杂性要求......
标签: c++ containers