如何在双端队列中随机访问元素会带来恒定的时间复杂度?

时间:2018-09-09 03:53:21

标签: c++

Deque为访问任何元素(cpp reference)提供了恒定的复杂性。在vector中,它始终是恒定的复杂性(vector中第一个元素的地址+没有元素),但是如何处理双端队列?双端队列元素不是连续的,那么如何给O(1)时间复杂度来访问任何元素?当我运行以下程序时,在使用vector的情况下,它给出正确的输出,但对于双端队列,它给出了一些任意数字(由于元素不连续,所以同意不给出正确的结果)。

vector<int> v1;
deque<int> d1;
for( int i =0; i < 1000000;++i)
    v1.push_back(i);
for( int j =0; j < 1000000;++j)
    d1.push_back(j);
cout << *(&v1[0] +90000) << endl; // output 90000
cout<<  *(&d1[0] +90000)<<endl;   // Output is not the same as expected

3 个答案:

答案 0 :(得分:6)

双端队列通常实现为两层结构,顶层是指向固定大小的块的指针数组。使用该大小的知识,确定哪个块包含感兴趣的项是恒定的复杂性,而确定请求该块中的哪个项的恒定复杂性。

仅仅因为它是常数并不意味着它总是一个简单的直接内存访问,只是针对该特定操作的所有访问都需要相同的步骤。

答案 1 :(得分:2)

不要让“ 1”混淆您。 O(1)是计算机科学的一种说法,即达到所需元素所需的计算步骤数不取决于容器的大小。无论您是拥有10个元素的std::deque<T>还是拥有10000000个元素的std::deque<T>都没关系-在索引 i 处获取所需元素总是涉及 2 指针取消引用。

请参见tutorial using tasks

  

典型的实现使用一系列单独分配的序列   固定大小的数组,带有额外的簿记,这意味着需要建立索引   访问双端队列必须执行两个指针取消引用

将其与std::list<T>进行比较,其中使元素位于索引 i 所需的计算步骤数确实取决于容器的大小。

答案 2 :(得分:1)

对双端队列元素的随机访问涉及两次指针取消引用,并且在任何元素上均保持不变。但是它不如向量有效。