【发布时间】:2021-08-24 18:14:57
【问题描述】:
这个问题可能听起来很原始,但它是在(最后)关于从列表中删除元素的(最佳情况)复杂性的(热烈)讨论的结果。
在发布此问题之前,我考虑了以下几点:
- 删除
List<>末尾元素的复杂度为 O(1) - 从静态数组中删除任何元素(甚至是最后一个元素)的复杂性为 O(n),因为它需要一个新数组。
现在请注意上述两个参数以及我们在 List<> 实现的背景中还有一个数组这一事实。
那么为什么List<> 操作会导致 O(1) 并且当两者都涉及重新创建数组时,数组也会导致 O(n)?或者我在这里错过了什么?谢谢!
更新:澄清一下,这个问题的主要焦点不是为什么最后一个元素删除的复杂性是 O(1),而是为什么它是 O(n) 的数组与 O(1) 的 List<>。标题已更新以反映更改。感谢答案(解决了它)和其他 cmets..`
【问题讨论】:
-
当您通过索引从
List<T>中删除一个项目时,您需要将列表中出现在它后面的所有项目向前复制一个空格,以缩小您刚刚留下的差距。如果您删除最后一个元素,那是免费的;如果删除第一个元素,则必须复制所有剩余元素。一般来说,从列表中删除任意元素的成本与列表中元素的数量成比例,使其成为O(n)。这个matches the docs -
@canton7 对。在数组的情况下它有什么不同?
-
@FailedScientist 查看我的完整答案
-
@FailedScientist 没有从数组中“删除”。您可以将剩余的 n-1 个元素复制到大小为 n-1 的数组中,这需要 O(n) 时间,或者您可以将索引处的元素设置为
null(或其他一些终端值),一个 O( 1) 操作。如果您按照List<>对其后备数组所做的操作,并将剩余的元素向前洗牌,那么您最终会在数组末尾获得空间,并使用 O(n) 算法。 -
复本用一句话说明,@canton7详细说明:去掉最后一项不做数组复制source.dot.net/#System.Private.CoreLib/List.cs,3d46113cc199059a