【问题标题】:Complexity Classes for a List [closed]列表的复杂性类[关闭]
【发布时间】:2013-11-18 20:30:23
【问题描述】:

为什么从数组或向量中删除一些东西是 O(n) 复杂度,而从列表中删除一些东西是 O(1) 复杂度?

【问题讨论】:

  • 你知道向量和列表是如何工作的吗?如果没有,我建议您使用good C++ book

标签: c++ arrays list vector time-complexity


【解决方案1】:

当你从一个向量中移除一个元素并且它不在最后一个位置时,你必须将所有后续元素向左移动一个位置。发生这种情况是因为对向量的要求是它的所有元素都形成一个连续的内存块,所以你不能有“洞”。对于list,元素在内存中的存储顺序没有要求,所以删除元素后不需要移动。

【讨论】:

  • 因此,当你从双端队列的中间移除时,你还必须移动元素和指针,这就是为什么从双端队列中移除也是 O(n) 复杂的原因class="comcopy">跨度>
  • 再一次,双端队列会将元素存储在连续的内存块中,因此无论何时删除中间某处的元素,都必须移动前面的元素或后面的元素。
  • @user2521432 这取决于你使用的双端队列的实现。
  • @user2521432 注意:与向量不同,从std::dequeeither 端删除和插入是 O(1)。向量最终只能获得这种好处;不是一开始。 两者都表现出 O(n) 的插入和删除中间序列。
  • @WhozCraig 我无法在这个工作地点检查 C++11 规范,但 IIRC,std::deque 并没有指定它最坏的情况 O (n) 用于插入和删除中间序列?您可以实现本质上是一个链表的双端队列,并且中间序列的插入和删除需要 O(1)。
【解决方案2】:

列表存储指向下一个和上一个条目的指针。因此,如果您想删除元素(您已经拥有指向它的迭代器/指针),只需更新 2 个指针并删除内存即可。向量连续存储内存,因此当您删除一个元素时,它必须将其后的所有元素移动到新的内存位置(最好的情况是删除最后一个元素 - 不需要移动任何项目;最坏的情况是删除第一个元素 - 所有其他项目都需要移动)。

列表操作

x->prev->next = x->next;
x->next->prev = x->prev;
delete x;

向量运算

for x to size - 1
    copy next memory block to previous

【讨论】:

    【解决方案3】:

    当您从数组中删除一项时(数组和向量使用连续内存),数组的其余部分需要移动。那是 O(N)。 在列表中,每个列表项都指向下一个和上一个,因此取消链接一个项目在 O(1) 中完成 - 无论列表长度如何。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 2023-01-09
      • 2012-09-08
      相关资源
      最近更新 更多