Підсумок Big-O для впровадження Java Collections Framework? [зачинено]


164

Я, можливо, незабаром буду викладати "курс краху Java". Хоча, мабуть, можна припустити, що члени аудиторії будуть знати нотацію Big-O, але, мабуть, не безпечно припустити, що вони будуть знати, яким є порядок проведення різних операцій з різних реалізацій колекцій.

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

Хтось має вказівники?


Ось посилання, яке мені виявилося корисним при обговоренні деяких дуже поширених об’єктів Java та скільки коштують їх операції за допомогою позначення Big-O. objectisissue.blogspot.com/2006/11/…
Нік

Хоча вони не є загальнодоступним доступом , прекрасні Java Generics and Collections Моріса Нафталіна та Філіпа Вадлера перелічують огляди інформації про час виконання у своїх розділах про різні класи колекцій.
Фабіан Стіг

Відповіді:


149

Цей веб-сайт досить хороший, але не стосується Java: http://bigocheatsheet.com/ Ось зображення на випадок, якщо це посилання не працюватиме


27
І саме тому ми не використовуємо URL-адреси як відповіді. Цей документ / сервер, наскільки я можу сказати, більше недоступний!
Джейсон Мок

1
@Ben J Посилання більше не працюють
Vikas V

Зараз посилання на веб-архів також порушені.
MikeFHay

Здається, додані нові робочі URL-адреси. Дякую за докладені зусилля, це дуже корисно.
Техас C

1
@AndreaZilio LinkedList.remove (Object) - це постійний час, припускаючи, що ви вже знаєте сусіда. Якщо ви не знаєте сусіда, лінійний час спочатку знайти його.
Пол Еванс

217

У книзі Java Generics and Collections є ця інформація (сторінки: 188, 211, 222, 240).

Реалізація списку:

                      get  add  contains next remove(0) iterator.remove
ArrayList             O(1) O(1) O(n)     O(1) O(n)      O(n)
LinkedList            O(n) O(1) O(n)     O(1) O(1)      O(1)
CopyOnWrite-ArrayList O(1) O(n) O(n)     O(1) O(n)      O(n)

Встановити реалізації:

                      add      contains next     notes
HashSet               O(1)     O(1)     O(h/n)   h is the table capacity
LinkedHashSet         O(1)     O(1)     O(1) 
CopyOnWriteArraySet   O(n)     O(n)     O(1) 
EnumSet               O(1)     O(1)     O(1) 
TreeSet               O(log n) O(log n) O(log n)
ConcurrentSkipListSet O(log n) O(log n) O(1)

Реалізація карти:

                      get      containsKey next     Notes
HashMap               O(1)     O(1)        O(h/n)   h is the table capacity
LinkedHashMap         O(1)     O(1)        O(1) 
IdentityHashMap       O(1)     O(1)        O(h/n)   h is the table capacity 
EnumMap               O(1)     O(1)        O(1) 
TreeMap               O(log n) O(log n)    O(log n) 
ConcurrentHashMap     O(1)     O(1)        O(h/n)   h is the table capacity 
ConcurrentSkipListMap O(log n) O(log n)    O(1)

Реалізація черги:

                      offer    peek poll     size
PriorityQueue         O(log n) O(1) O(log n) O(1)
ConcurrentLinkedQueue O(1)     O(1) O(1)     O(n)
ArrayBlockingQueue    O(1)     O(1) O(1)     O(1)
LinkedBlockingQueue   O(1)     O(1) O(1)     O(1)
PriorityBlockingQueue O(log n) O(1) O(log n) O(1)
DelayQueue            O(log n) O(1) O(log n) O(1)
LinkedList            O(1)     O(1) O(1)     O(1)
ArrayDeque            O(1)     O(1) O(1)     O(1)
LinkedBlockingDeque   O(1)     O(1) O(1)     O(1)

Внизу javadoc для пакету java.util міститься кілька хороших посилань:


3
Ви повинні вказати, для якого сценарію випадку є ті фігури, наприклад, видалення з Arraylist може взяти O (n), якщо ви видалите елемент в середині або в кінці масиву.
Popeye

@popeye - це зазвичай не найгірший випадок?
Яссін Хаджай

Як згадував @Popeye, має бути чіткий опис того, в якому випадку йдеться про відповідь. Випадок може бути середнім / найгіршим за часом складності. Схоже, відповідь стосується "середнього" випадку для всіх DS.
Yashwin Munsadwala

12

Javadocs від Sun для кожного класу колекцій, як правило, скаже вам саме те, що ви хочете. HashMap , наприклад:

Ця реалізація забезпечує продуктивність у постійному часі для основних операцій (get and put), припускаючи, що хеш-функція належним чином розподіляє елементи між відрами. Ітерація над переглядами колекції вимагає часу, пропорційного "потужності" екземпляра HashMap (кількість відра) плюс його розміру (кількість відображень ключових значень).

Дерево карта :

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

Дерево :

Ця реалізація забезпечує гарантовану вартість журналу (n) часу для основних операцій (додавання, видалення та вміст).

(наголос мій)


Я не згоден з частиною HashMap. Я знаю положення Sun, але ... get для прикладу повинен викликати obj.equals (ключ), який може бути лінійним за розміром об'єктів, що містяться. Врахуйте, що зазвичай для цього порівняння потрібно прочитати поля. Виняток становлять цілі чи рядки (інтерновані) ???
Переплив

Перш за все, якщо вони помиляються, вам не повинно бути занадто важко створити тестовий випадок, який спростує продуктивність постійного часу? По-друге, якщо ви подивитеся на вихідний код для HashMap, він не викликає рівнянь () проти кожного ключа на карті - лише тоді, коли хеш-коди рівні.
мат б

5
Якщо ви читаєте цитату вище, вона говорить, що це постійний час, "якщо припустити, що хеш-функція належним чином розподіляє елементи між відрами". З теорії CS, хеш-таблиці мають постійні часові операції, коли хеш-функція "хороша" (що трапляється в середньому), але може зайняти лінійний час у гіршому випадку.
newacct

4
@Overflown - технічно неважливо, скільки часу obj.equals () займає з точки зору складності, оскільки це лише частина "константи" щодо кількості предметів у колекції.
mikera

6

Хлопець вище дав порівняння для HashMap / HashSet проти TreeMap / TreeSet.

Я розповім про ArrayList vs. LinkedList:

ArrayList:

  • O (1) get()
  • амортизований O (1) add()
  • якщо ви вставляєте або видаляєте елемент в середині за допомогою, ListIterator.add()або Iterator.remove(), це буде O (n), щоб перемістити всі наступні елементи

LinkedList:

  • O (n) get()
  • O (1) add()
  • якщо ви вставите або видалите елемент в середині за допомогою, ListIterator.add()або Iterator.remove()це буде O (1)

1
if you insert or delete an element in the middle using ListIterator.add() or Iterator.remove(), it will be O(1) чому? спочатку нам потрібно знайти елемент посередині, то чому б це не O (n)?
MyTitle

@MyTitle: прочитайте його ще раз. "using ListIterator.add()або Iterator.remove()" У нас є ітератор.
newacct
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.