我有以下问题:
List<int> list = new List<int>(10);
for (int i = 0; i < 10; i++)
list.Add(i);
现在list.Count和list.Capacity是10.没关系。但是当我尝试删除第一项时会发生什么?
list.RemoveAt(0);
计数现在是9而容量仍然是10,但是列表内部发生了什么?列表必须经历所有元素,如:
list[0] = list[1];
list[1] = list[2];
// etc...
list[9] = null;
可能更好的只是自己做就像:
list[0] = list[list.Count - 1];
?但在这种情况下,项目顺序将会改变。
如果我有一个具有预初始化长度的10000000个元素的列表,那么list.RemoveAt(0)需要多长时间?如果List没有预定长度会有什么不同吗?
UPD:
注意来源(不知道他们是免费访问o.O):
// Removes the element at the given index. The size of the list is
// decreased by one.
//
public void RemoveAt(int index) {
if ((uint)index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
_size--;
if (index < _size) {
Array.Copy(_items, index + 1, _items, index, _size - index);
}
_items[_size] = default(T);
_version++;
}
所以它里面确实有Array.Copy。太遗憾了。 感谢@TomTom。
答案 0 :(得分:0)
看看LinkedList。只删除项目from it
的O(1)答案 1 :(得分:0)
正如您指出的通用List,RemoveAt(0)操作将采用O(N)作为N个项目的列表。 (因为它将处理N个项目)。这是因为List由数组支持。
按MSDN,从带有计数C的List中删除索引I需要C - I.您可以使用它来回答关于初始容量的问题(没有它没有帮助)
您可以使用其他数据结构,例如作为链接列表(顾名思义)编写的LinkedList,并删除O(1)中的第1项。但是,其他操作明显比List
差答案 2 :(得分:0)
这就是:
public void RemoveAt(int index) {
if ((uint)index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
Contract.EndContractBlock();
_size--;
if (index < _size) {
Array.Copy(_items, index + 1, _items, index, _size - index);
}
_items[_size] = default(T);
_version++;
}
查看:
http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,3d46113cc199059a
双链表是最快的,或使用不安全的指针更改。
答案 3 :(得分:0)
你怎么去List的来源并检查然后写一些测试?显然这对你非常重要。无论如何,你所提出的大量问题都让这个问题过于宽泛。
一般来说,由于来源是公开的,如果经常有助于调查它们。