Изменения в связанном списке включают две операции:
- поиск узла для добавления нового узла к
- фактически добавляет узел, изменяя указатели узла
В связанном списке вторая операция - это операция O(1)
, поэтому она зависит от стоимости первых операций.
При добавлении к последнему узлу наивные реализации связанного списка приводят к O(n)
времени итерации. Тем не менее, хорошие библиотеки связанных списков будут учитывать наиболее распространенные варианты использования и особый случай доступа к последнему узлу. Эта оптимизация приведет к O(1)
извлечению последнего элемента, что приведет к общему O(1)
времени вставки до конца.
Что касается середины, ваш анализ правилен в том смысле, что нахождение узла также займет O(n)
. Однако некоторые библиотеки предоставляют метод, который будет принимать указатель на то место, куда должен быть вставлен новый узел, а не на индекс (например, C++
list
). Это исключает линейные затраты, в результате чего в целом O(1)
.
Хотя вставка в середину обычно рассматривается как операция O(n)
, в некоторых случаях ее можно оптимизировать до O(1)
. Это противоположно списку массивов, где сама операция вставки (вторая операция) равна O(n)
, так как все элементы в более высоких местах должны быть перемещены. Эта операция не может быть оптимизирована.
За диссертацию
Наивная реализация связанного списка привела бы к O(n)
времени вставки. Тем не менее, хорошие составители библиотек связанных списков оптимизировали бы для общих случаев, поэтому они сохраняли бы ссылку на последние элементы (или имели бы реализацию циклического связанного списка), в результате чего O(1)
время вставки.
Что касается вставки в середину. В некоторых библиотеках, таких как C++
, есть место для вставки. Они взяли бы указатель на узел списка, к которому добавляется новый. Такие вставки будут стоить O(1)
. Я не думаю, что вы можете достичь O(1)
по номеру индекса.
Это применяется к списку массивов, где вставка в средние силы переупорядочивает все элементы выше его, поэтому это должна быть операция O(n)
.