Если бы существовала такая структура, все использовали бы ее вместо массивов.
Однако я считаю более близкую структуру, о которой мне рассказывали в университетской лекции. Он имеет постоянное время доступа и время добавления/удаления элемента в произвольную позицию в основном O (sqrt (N)), и только когда N пересекает квадрат целочисленного значения, он принимает O (N). Амортизированное время - O (sqrt (N)). Вот идея.
N элементов в этой структуре хранятся в непрерывном массиве, который разделен на квадраты sqrt (N) смежных элементов sqrt (N) (возможно, последний фрагмент содержит меньше элементов). Каждый кусок - это ring buffer, для которого позиция первого элемента хранится в отдельном массиве sqrt (N). Чтобы получить доступ к элементу, вы должны определить, в каком фрагменте он находится (принимает одно деление), и выполнить правильный сдвиг в кольцевом буфере (сумма и модуль). Это постоянное время для доступа.
Чтобы добавить элемент до i-го положения, определите кусок k
, элемент будет в конечном итоге, а затем отметьте все последние элементы в каждом фрагменте в k
.. sqrt(N)-1
. Сдвиньте отмеченный элемент в предыдущем фрагменте в свободный слот в последнем фрагменте, который будет главой кольцевого буфера (доступ к дополнительному массиву для определения где именно). Затем в положение перемещенного элемента из предыдущего фрагмента перемещайте отмеченный элемент из пред-предыдущего фрагмента. Повторите это, и вы получите свободный слот в середине массива, чтобы разместить элемент, который вы собираетесь добавить.
Магия заключается в том, что вы должны только увеличивать значения в дополнительном массиве на единицу (принимает время O (sqrt (N)), что делает структуру последовательной для доступа снова. Магия sqrt (N) также находится здесь: вы должны работать с каждым из X кусков и по каждому из элементов N/X вспомогательного массива. min (X + N/X) достигается для X = sqrt (N).
Если нет места в последней порции, чтобы добавить еще один элемент (т.е. SQRT (N), используемые до сих пор слишком мал), переупакуйте массив с SQRT (N) увеличивается на единицу. Это занимает время O (N). Амортизированное время по-прежнему равно O (sqrt (N)) за элемент.
Поэтому добавление элемента в произвольное место массива принимает O (sqrt (N)). Удаление происходит в одно и то же время. Время доступа принимает O (1).
Это идея.Я не знаю, как это называется, и профессор не знал ни того, что сам изобрел его. Любые ссылки будут оценены. И OP мог его реализовать, но, я уверен, кто-то уже имеет.
Итак, у вас есть список, где вам нужно регулярно выращивать список и извлекать элементы из него по индексу? – aperkins
AFAIK, ArrayList удваивает его емкость при превышении его текущей емкости. Таким образом, будут O (log (n)) копии, где n - конечная емкость List. Это означает, что количество фактических времен, когда нужно скопировать весь список, очень мало. Вероятно, вы начнете исчерпывать память задолго до того, как накладные расходы станут значительными. OTOH, если вы должны остановить копии и заранее знать верхнюю границу числа элементов, которые должны удерживать список, вы можете просто передать максимальный размер в качестве аргумента в конструктор ArrayList. – MAK
есть практическая причина, в которой вы нуждаетесь? имеет контрольный показатель/профиль, показывающий, что арраист будет вашим узким местом? – basszero