列出<t>具有固定容量项目删除处理时间/ C#</t>

时间:2014-11-18 11:18:00

标签: c# list time-complexity

我有以下问题:

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。

4 个答案:

答案 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的来源并检查然后写一些测试?显然这对你非常重要。无论如何,你所提出的大量问题都让这个问题过于宽泛。

一般来说,由于来源是公开的,如果经常有助于调查它们。