Массив, который можно быстро изменить
Я ищу тип данных массива, который может легко добавлять элементы без повышения производительности.
- Система. Массив -
Redim Preserve
копирует всю оперативную память от старого к новому, так же медленно, как и количество существующих элементов.
- System.Collections. ArrayList - достаточно хорошо?
- System.Collections. IList - достаточно хорошо?
Ответы
Ответ 1
Просто подведем несколько структур данных:
System.Collections.ArrayList: нетипизированные структуры данных устарели. Вместо этого используйте List (t).
System.Collections.Generic.List(из t): это представляет собой изменяемый размер массива. Эта структура данных использует внутренний массив за кулисами. Добавление элементов в список равно O (1) до тех пор, пока базовый массив не будет заполнен, иначе его O (n + 1) изменит размер внутреннего массива и скопирует элементы.
List<int> nums = new List<int>(3); // creates a resizable array
// which can hold 3 elements
nums.Add(1);
// adds item in O(1). nums.Capacity = 3, nums.Count = 1
nums.Add(2);
// adds item in O(1). nums.Capacity = 3, nums.Count = 3
nums.Add(3);
// adds item in O(1). nums.Capacity = 3, nums.Count = 3
nums.Add(4);
// adds item in O(n). Lists doubles the size of our internal array, so
// nums.Capacity = 6, nums.count = 4
Добавление элементов эффективно только при добавлении в конец списка. Вставка в середине заставляет массив перемещать все элементы вперед, что является операцией O (n). Удаление элементов также равно O (n), так как массиву необходимо переместить элементы назад.
System.Collections.Generic.LinkedList(из t): если вам не нужен случайный или индексированный доступ к элементам в вашем списке, например, вы планируете добавлять элементы и итерации с первого для продолжения, тогда LinkedList - ваш друг. Вставками и удалениями являются O (1), поиск - O (n).
Ответ 2
Для этого вам следует использовать Generic List < > (System.Collections.Generic.List). Он работает в постоянном амортизированном времени.
Он также имеет следующие функции с массивами.
- Быстрый произвольный доступ (вы можете получить доступ к любому элементу в списке в O (1))
- Быстро перевернуть
- Медленно вставлять и удалять объекты в начале или в середине (так как он должен делать копию всего списка)
Если вам нужны быстрые вставки и удаления в начале или конце, используйте либо связанный список, либо очереди
Ответ 3
Будет ли LinkedList <T> работает для вас? Это не (в некоторых случаях) как интуитивное, как прямой массив, но очень быстрый.
- AddLast для добавления в конец
- AddBefore/AddAfter для вставки в список
- AddFirst для добавления в начало
Однако это не так быстро для случайного доступа, поскольку вам нужно перебирать структуру для доступа к вашим элементам... однако у нее есть методы .ToList() и .ToArray() для захвата копии структуры в списке /array, поэтому для доступа к чтению вы можете сделать это в крайнем случае. Увеличение производительности вставки может перевешивать снижение производительности в случае произвольного доступа, или это может быть не так. Это будет полностью зависеть от вашей ситуации.
Там также эта ссылка, которая поможет вам решить, какой именно путь:
Когда использовать связанный список по списку массивов/массивов?
Ответ 4
Что для вас "достаточно хорошо"? Что именно вы хотите сделать с этой структурой данных?
Нет структуры массива (т.е. доступ O (n)) позволяет вставить в середину без O (n) времени исполнения; вставка в конце - это O (n) наихудший случай, а O (1) амортизируется для массивов с самоуничтожением, таких как ArrayList.
Может быть hashtables (амортизированный O (1) доступ и вставка в любом месте, но O (n) наихудший случай для вставки) или деревья (O (log (n)) для доступа и вставки где угодно, гарантировано) лучше подходят.
Ответ 5
Если скорость ваша проблема, я не вижу, как выбранный ответ лучше, чем использование необработанного массива, хотя он и изменяет размеры, он использует тот же механизм, который вы использовали бы для изменения размера массива (и должен дольше), если вы всегда добавляете в конец, и в этом случае он должен делать что-то немного умнее, потому что он выделяет кусок за раз, а не только один элемент.
Если вы часто добавляете около начала/середины своей коллекции и не часто указываете на середину/конец очень часто, вам, вероятно, нужен связанный список. Это будет иметь самое быстрое время вставки и будет иметь большое время итерации, оно просто засасывает при индексировании (например, глядя на третий элемент с конца или на 72-й элемент).