Асимптотическая сложность of.NET классы коллекции

есть ли какие-либо ресурсы об асимптотической сложности (big-O и остальные) методов классов коллекции .NET (Dictionary<K,V>, List<T> etc...)?

Я знаю, что документация библиотеки C5 включает некоторую информацию об этом (пример), но меня тоже интересуют стандартные коллекции .NET... (и информация PowerCollections также была бы приятной).

6 ответов


MSDN перечисляет эти:

etc. Например:

общий список сортировки(TKey, TValue) class-это двоичное дерево поиска с O (log n) извлечение, где n - количество элементов в словаре. В этом он похож на Sorteddictionary (TKey, TValue) generic класс. Два класса имеют сходные объектные модели, и оба имеют O (log n) поиск. Где два класса отличаются в использовании памяти и скорости вставка и удаление:

SortedList (TKey, TValue) использует меньше память, чем SortedDictionary(TKey, TValue).

SortedDictionary (TKey, TValue) имеет более быстрые ввод и удаление операции для несортированных данных, O (log n) в отличие от O (n) для SortedList (TKey, TValue).

если список заполняется сразу из отсортированных данных, SortedList(TKey, TValue) быстрее, чем SortedDictionary (TKey, TValue).


на этой странице суммирует некоторые сложности времени для различных типов коллекций С Java, хотя они должны быть точно такими же для .Сеть.

Я взял таблицы с этой страницы и изменил/расширил их для .NET framework. См. также страницы MSDN для SortedDictionary и объект sortedlist, которые детализируют сложности времени, необходимые для различных оперативный.


Поиск

Type of Search/Collection Types           Complexity  Comments
Linear search Array/ArrayList/LinkedList  O(N)        Unsorted data.
Binary search sorted Array/ArrayList/     O(log N)    Requires sorted data.
Search Hashtable/Dictionary<T>            O(1)        Uses hash function.
Binary search SortedDictionary/SortedKey  O(log N)    Sorting is automated.

извлечение и вставка

Operation         Array/ArrayList  LinkedList  SortedDictionary  SortedList
Access back       O(1)             O(1)        O(log N)          O(log N)
Access front      O(1)             O(1)        N.A.              N.A.
Access middle     O(1)             O(N)        N.A.              N.A.
Insert at back    O(1)             O(1)        O(log N)          O(N)
Insert at front   O(N)             O(1)        N.A.              N.A.
Insert in middle  O(N)             O(1)        N.A.              N.A.

удаление должно иметь ту же сложность, что и вставка для связанной коллекции.

SortedList имеет несколько примечательных особенностей для вставки и извлечения.

вставка (добавить метод):

этот метод является операцией o(n) для несортированные данные, где n-количество. Это операция O (log n), если новый элемент добавляется в конце список. Если вставка вызывает изменение размера, операция O (n).

извлечение (свойство товара):

получение значения этого свойства является операцией O(log n), где n Рассчитывать. Установив свойство O (log n) операция, если ключ уже в списке сортировки)>). Если ключ не в список, установка свойства является O(n) операция по несортированные данные или O (log n) если новый элемент добавлен в конец списка. Если вставка приводит к изменение размера, операция O (n).

отметим, что ArrayList эквивалентно List<T> С точки зрения трудоемкости всех операций.



Я вообще не знаю (другой ответ, только что опубликованный, возможно, дает вам именно то, что вам нужно), но вы можете отразить это и другие методы, конечно, используя ILSpy (немного неудобно с кодом FSharp, true), и это в конечном итоге дает эту функцию как C#:

internal static a maximumElementAux<a>(SetTree<a> s, a n)
{
  while (true)
  {
    SetTree<a> setTree = s;
    if (setTree is SetTree<a>.SetOne)
    {
      break;
    }
    if (setTree == null)
    {
      return n;
    }
    SetTree<a>.SetNode setNode = (SetTree<a>.SetNode)s;
    SetTree<a> arg_23_0 = setNode.item3;
    n = setNode.item1;
    s = arg_23_0;
  }
  return ((SetTree<a>.SetOne)s).item;
  return n;
}

хорошо, так что это не совсем "правильный" код в терминах C#, но наличие while(true) цикл подразумевает, что он не может быть O(1) по крайней мере; что касается того, что это на самом деле... что ж, у меня слишком болит голова, чтобы это выяснить. :)


на данной странице представлены краткие заметки о некоторых ключевых плюсах и минусах для большинства коллекций .NET:

http://geekswithblogs.net/BlackRabbitCoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx


нет такой вещи, как "сложность классов коллекции". Скорее, различные операции над этими коллекциями имеют разные сложности. Например, добавление элемента в Dictionary<K, V>...

...приближаетсяO (1) операции. Если емкость должна быть увеличена для размещения нового элемента, этот метод становится O (n) операции, где n is Count.

в то время как получение элемент Dictionary<K, V>...

...подходит к операции O(1).


в документации говорится, что он построен на двоичном дереве и не упоминает отслеживание максимального элемента. Если документация верна, это означает, что она должна быть O( log n). В документации по коллекциям была, по крайней мере, одна ошибка (ссылка на структуру данных с поддержкой массива как на двоичное дерево поиска), но это было исправлено.