Прежде всего вам нужно рассмотреть, будет ли вы удалять из центра списка часто по сравнению с длиной списка. Если ваш список содержит N
элементов, но вы удаляете гораздо реже, чем 1/N
, не беспокойтесь об этом. Используйте LinkedList
или ArrayDeque
, как пожелаете. (Если ваши списки иногда огромны, а затем уменьшаются, но в основном небольшие, то LinkedList
лучше, так как восстановить память невозможно, в противном случае ArrayDeque
не нуждается в дополнительных объектах, поэтому он немного быстрее и компактнее - кроме базовых массив никогда не уменьшится)
Если, с другой стороны, вы удаляете совсем немного чаще, чем 1/N
, то вам следует рассмотреть LinkedHashSet
, который поддерживает связанные очереди списка на вершине хэша-набор. - но набор, поэтому имейте в виду, что вы не можете хранить повторяющиеся элементы. У этого есть накладные расходы LinkedList
и ArrayDeque
, но если вы делаете центральные удаления часто, это, вероятно, будет стоить того.
Оптимальная структура, однако, если вам действительно нужна каждая минута скорости и вы готовы потратить время кодирования, чтобы получить ее, это будет «изменяемый размер» массива (т.е. перераспределяется, когда он слишком мал) с круговой буфер, где вы можете пропустить элементы из середины, установив их в null. (Вы также можете перераспределить буфер, когда слишком много было пустым, если у вас был случай с неправильным использованием.) Я не рекомендую кодировать это, если вы не действительно наслаждаетесь кодированием высокопроизводительных структур данных или не имеете убедительных доказательств того, что это один из ключевые узкие места в вашем коде и, следовательно, вам это действительно нужно.
Думать о скиписте? http://en.wikipedia.org/wiki/Skip_list Причины добавления и удаления для O (log n) –
Да, я изучал скипистов по pugh et al, они кажутся жизнеспособным решением – 2010-02-28 19:19:11