Чому вставляється посередині пов'язаного списку O (1)?


105

Згідно зі статтею Вікіпедії у зв’язаних списках , вставлення в середині зв'язаного списку вважається O (1). Я б подумав, що це буде O (n). Чи не потрібно вам знаходити вузол, який може бути в кінці списку?

Чи не враховує цей аналіз знаходження операції з вузлом (хоча це потрібно), а лише сама вставка?

Редагувати :

Пов'язані списки мають ряд переваг перед масивами. Вставка елемента в конкретну точку списку - це операція постійного часу, тоді як для вставки в масив може знадобитися переміщення половини елементів або більше.

Наведене вище твердження мене трохи вводить в оману. Виправте мене, якщо я помиляюся, але, думаю, висновок повинен бути таким:

Масиви:

  • Пошук точки вставки / видалення O (1)
  • Виконання вставки / видалення O (n)

Пов'язані списки:

  • Пошук точки вставки / видалення O (n)
  • Виконання вставки / видалення O (1)

Я думаю, що єдиний раз, коли б вам не довелося знайти позицію, це якщо б ви тримали якийсь вказівник на нього (як у випадку з головою та хвостом у деяких випадках). Тож ми не можемо однозначно сказати, що пов'язані списки завжди б'ють масиви для опцій вставки / видалення.

Відповіді:


113

Ви праві, стаття розглядає "Індексацію" як окрему операцію. Отже, вставка сама O (1), але потрапляння до цього середнього вузла - це O (n).


3
Що робить більшу різницю, якщо вставляти більше одного об’єкта на одне і те ж місце ...
Має QUIT - Anonymous-Mousse

@ Аноні-Мус, чи можете ви пояснити це трохи більше? тобто нам потрібно знайти місце вставки лише один раз, вставляючи кілька об'єктів?
MyTitle

2
Це розмір O (n) у розмірі наявного списку, а не кількість вставок, які ви плануєте зробити там.
Має QUIT - Anonymous-Mousse


25

Ні, коли ви вирішите, що хочете вставити, передбачається, що ви вже в середині ітерації через список.

Операції на пов'язаних списках часто робляться таким чином, що вони насправді не трактуються як загальний "список", а як набір вузлів - подумайте про сам вузол як ітератор для вашого основного циклу. Отже, переглядаючи список, ви помічаєте, як частину вашої бізнес-логіки, що новий вузол потрібно додати (або старий видалити), і ви це зробите. Ви можете додати 50 вузлів за одну ітерацію, і кожен з цих вузлів - це лише О (1) час від’єднати два сусідніх вузла та вставити новий.

Редагувати: Людина, ти набираєш другий абзац і раптом замість того, щоб бути першим відповідачем, ти 5-й кажеш те саме, що і перші 4!


1
Так, це відстійно ... Я поставив +1 своєму, тому що варто зазначити, що складність вставки зв'язаних списків розглядається в контексті вже знаходження на потрібному покажчику.
Даніель Макіас

6

Для порівняння з масивом, який показує цей графік, це O (1), тому що вам не потрібно переміщувати всі елементи після нового вузла.

Так, так, вони припускають, що ви вже маєте вказівник на цей вузол, або що отримання покажчика є тривіальним. Іншими словами, заявлена ​​проблема: " заданий вузол у X , який код потрібно вставити після цього вузла?" Ви починаєте з точки вставки.


5

Вставлення до пов'язаного списку відрізняється від повторення через нього. Ви не знаходите елемент, ви скидаєте покажчики, щоб помістити його туди. Не має значення, чи буде вона вставлена ​​поблизу переднього кінця чи в кінці, вставка все ще включає переназначення покажчиків. Звичайно, це залежатиме від того, як це було реалізовано, але це сила списків - ви можете легко вставити. Доступ через індекс - це місце, де світить масив. Для списку, однак, зазвичай буде O (n) знайти n-й елемент. Принаймні, це я пам’ятаю ще зі школи.


3

Тому що це не передбачає ніякого циклічного циклу.

Вставлення виглядає так:

  • вставляючий елемент
  • посилання на попередній
  • посилання на наступне
  • зроблено

це постійний час у будь-якому випадку.

Отже, вставляючи n елементів один за одним є O (n).


3

Чи не враховує цей аналіз знаходження операції з вузлом (хоча це потрібно), а лише сама вставка?

Ти маєш це. Вставка в заданій точці передбачає, що ви вже тримаєте вказівник на елемент, який ви хочете вставити після:

InsertItem(item * newItem, item * afterItem)


2

Ні, це не враховує пошук. Але якщо ви вже маєте вказівник на елемент посередині списку, то вставте в цій точці O (1).

Якщо вам доведеться його шукати, вам доведеться додати час пошуку, який повинен бути O (n).


0

У статті йдеться про порівняння масивів зі списками. Пошук позиції вставки для масивів і списків є O (N), тому стаття ігнорує його.


1
Чи не знайдемо точку вставки масиву O (1)? Оскільки масиви зберігаються в суміжній пам'яті, все, що потрібно зробити, - це додати зміщення.
Роб Соберс

@ vg1890 - Ви повинні спочатку знайти зсув.

0

O (1) залежить від того факту, що у вас є предмет, куди ви будете вставляти новий елемент. (до або після). Якщо ви цього не зробите, ви повинні знайти цей предмет.


0

Я думаю, що це лише випадок того, що ви вирішили вважати нотацією O (). У разі вставки звичайної операції рахувати - це операції копіювання. За допомогою масиву вставка в середину передбачає копіювання всього, що знаходиться вище в пам'яті. При пов'язаному списку це стає встановленням двох покажчиків. Вам потрібно знайти місце, незалежно від того, що потрібно вставити.


0

Якщо у вас є посилання на вузол, який потрібно вставити після операції, це O (1) для пов'язаного списку.
Для масиву це все ще O (n), оскільки вам потрібно перемістити всі послідовні вузли.


0

Найбільш поширені випадки, ймовірно, вставляють на початку або в кінці списку (а кінці списку можуть зайняти не потрібний час).

На противагу цьому, вставляючи елементи на початку або в кінці масиву (для чого потрібно змінити розмір масиву, якщо він знаходиться в кінці, або змінити розмір і перемістити всі елементи, якщо він знаходиться на початку).


Можна вставити елементи в кінець масиву як O (1), якщо ви зберігаєте буфер порожніх елементів в кінці, хоча інколи вставки все одно будуть O (1). Більшість колекцій це роблять. Також можна зробити елементи інерції на початку масиву бути O (1), змінивши свій оператор індексу, щоб повернути номер елемента (n + x)% len, де x - кількість разів, коли ви вставили елементи на початку списку. Деки іноді реалізовуються так (але також іноді реалізуються із подвійними зв’язками списків.
Брайан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.