【问题标题】:how does random access of an element in deque gives constant time complexity? [duplicate]deque 中元素的随机访问如何给出恒定的时间复杂度? [复制]
【发布时间】:2018-09-09 03:53:20
【问题描述】:

Deque 为访问任何元素(cpp reference)提供了恒定的复杂性。在 Vector 中,它始终是恒定的复杂性(vector 中第一个元素的地址 + 元素的数量 * 每个元素的大小),但它对 Deque 是如何工作的?双端队列元素在内存中是不连续的,那么它如何实现 O(1) 时间复杂度来访问任何元素呢?当我运行以下程序时,对于 Vector,它给出了正确的输出,但对于 Deque,它给出了一些任意数字(同意不给出正确的结果,因为元素不连续)。

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 90000

【问题讨论】:

  • 我觉得你链接的前几段应该回答你的问题......

标签: c++


【解决方案1】:

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

仅仅因为它是常量并不表示它总是简单的直接内存访问,只是该特定操作的所有访问都需要相同的步骤。

【讨论】:

  • “仅仅因为它是常量并不表示它总是一个简单的直接内存访问,只是该特定操作的所有访问都需要相同的步骤”-错了..相同的步骤可以例如,“迭代所有元素”,这使得它成为 O(n)..
  • @Dr.Haimovitz 这取决于您将什么视为“相同的步骤”。
  • @Dr.Haimovitz 此处使用的“步骤”一词可能确实意味着需要O(1) 的简单操作。
  • “使用该大小的知识,确定哪个块包含感兴趣的项目是恒定的复杂性” - 如果这些块不是连续内存的一部分,您能解释一下如何吗??
  • @Dr.Haimovitz 块在内存中的哪个位置相互关联并不重要。找到指向任何块的指针是常数时间,索引该指针以获取值是常数时间。访问双端队列的任何元素都是同样的努力,n 的值无关紧要。如果总是需要 100 次操作和 10 秒才能在虚拟容器中找到任何值,那么访问仍然是 O(1)。它是复杂性的衡量标准,而不是时间。
【解决方案2】:

不要让“1”让您感到困惑。 O(1) 是计算机科学的说法,即达到所需元素所需的计算步骤数不取决于容器的大小。无论您是拥有 10 个元素的 std::deque&lt;T&gt; 还是拥有 10000000 个元素的 std::deque&lt;T&gt; 都无关紧要 - 在索引 i 处获取所需元素总是涉及 两个 指针取消引用。

见https://en.cppreference.com/w/cpp/container/deque:

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

将此与 std::list&lt;T&gt; 进行比较,其中获取索引 i 处的元素所需的计算步骤数确实取决于容器的大小。

【讨论】:

  • 如果第一个数组或第一个块已满并且有一个入队操作会发生什么情况,必须分配一个新数组(它是 O(1)),因为该数组是固定大小的,但是如何簿记更新,因此例如索引 0 的下一个随机访问将选择正确的元素,在新数组索引 0 指向另一个数组之前,如果更改得当,这个映射还必须更改每个其他索引映射,即 O(n ) 表示元素的插入仅在 *avarage 中为 o(1),因为每次其中一个数组已满时,都需要一个新的映射 (n)
  • “如果第一个数组或第一个块已满并且有一个入队操作会发生什么” - 这个问题是关于随机访问,而不是关于修改容器。请不要试图让这看起来比实际更复杂。
【解决方案3】:

对双端队列元素的随机访问涉及两个指针取消引用,并且在任何元素中都是恒定的。但是它不会像向量那样有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 2013-11-09
    • 2017-01-28
    相关资源
    最近更新 更多