Чтобы ответить на ваш другой вопрос: добавление элемента в конец ArrayList
или аналогичного занимает амортизированное O (1) время, пока существует любой коэффициент k> 1 таким образом, что перераспределение всегда создает массив, который в k раз больше предыдущего.
Фактический используемый фактор не имеет большого значения, если он больше единицы. Альтернативные схемы перераспределения могут иметь различную сложность. Если перераспределение добавляет, например, постоянную сумму, то добавление элемента занимает амортизированное O (N) время.
Вот почему все профессионально написанные динамически растущие массивы растут по одному фактору каждый раз. Коэффициент обеспечивает фиксированную верхнюю границу для доли потраченного впустую пространства ( (k-1) / k ), рассчитанную на фиксированную верхнюю границу для среднего числа копий каждого элемента в последовательности из добавляет.
Допустим, вы используете коэффициент k и только что выполнили перераспределение Nth . Это означает, что вы добавили около k ^ N предметов. Сколько предметов вы скопировали? Пусть будет C . Тогда:
C = k ^ (N-1) + k (N-2) + ... + 1
kC - C = k ^ N + k ^ (N-1) - k ^ (N-1) + k ^ (N-2) - k ^ (N-2) ... - 1
кС - C = k ^ N - 1
C = (k ^ N-1) / (k-1)
Количество копий на каждый добавленный элемент , затем C / K ^ N , что в значительной степени 1 / (k-1) .
Таким образом, коэффициент Java k = 2 означает, что на одну операцию добавления приходится около одной копии, с количеством неиспользуемых слотов до 50% , а коэффициент CPython k = 1,125. означает, что на операцию добавления приходится около 8 копий с количеством неиспользуемых слотов до 11% .