【发布时间】:2013-11-18 20:30:23
【问题描述】:
为什么从数组或向量中删除一些东西是 O(n) 复杂度,而从列表中删除一些东西是 O(1) 复杂度?
【问题讨论】:
-
你知道向量和列表是如何工作的吗?如果没有,我建议您使用good C++ book
标签: c++ arrays list vector time-complexity
为什么从数组或向量中删除一些东西是 O(n) 复杂度,而从列表中删除一些东西是 O(1) 复杂度?
【问题讨论】:
标签: c++ arrays list vector time-complexity
当你从一个向量中移除一个元素并且它不在最后一个位置时,你必须将所有后续元素向左移动一个位置。发生这种情况是因为对向量的要求是它的所有元素都形成一个连续的内存块,所以你不能有“洞”。对于list,元素在内存中的存储顺序没有要求,所以删除元素后不需要移动。
【讨论】:
std::deque 的 either 端删除和插入是 O(1)。向量最终只能获得这种好处;不是一开始。 两者都表现出 O(n) 的插入和删除中间序列。
std::deque 并没有指定它最坏的情况 O (n) 用于插入和删除中间序列?您可以实现本质上是一个链表的双端队列,并且中间序列的插入和删除需要 O(1)。
列表存储指向下一个和上一个条目的指针。因此,如果您想删除元素(您已经拥有指向它的迭代器/指针),只需更新 2 个指针并删除内存即可。向量连续存储内存,因此当您删除一个元素时,它必须将其后的所有元素移动到新的内存位置(最好的情况是删除最后一个元素 - 不需要移动任何项目;最坏的情况是删除第一个元素 - 所有其他项目都需要移动)。
列表操作
x->prev->next = x->next;
x->next->prev = x->prev;
delete x;
向量运算
for x to size - 1
copy next memory block to previous
【讨论】:
当您从数组中删除一项时(数组和向量使用连续内存),数组的其余部分需要移动。那是 O(N)。 在列表中,每个列表项都指向下一个和上一个,因此取消链接一个项目在 O(1) 中完成 - 无论列表长度如何。
【讨论】: