Ringkasan Big-O untuk implementasi Java Collections Framework? [Tutup]


164

Saya mungkin akan mengajar "kursus kilat Java" segera. Meskipun mungkin aman untuk menganggap bahwa anggota audiens akan mengetahui notasi Big-O, mungkin tidak aman untuk mengasumsikan bahwa mereka akan tahu apa urutan berbagai operasi pada berbagai implementasi pengumpulan.

Saya dapat mengambil waktu untuk membuat ringkasan matriks sendiri, tetapi jika sudah ada di domain publik di suatu tempat, saya yakin ingin menggunakannya kembali (dengan kredit yang tepat, tentu saja.)

Adakah yang punya petunjuk?


Berikut adalah tautan yang saya temukan berguna ketika mendiskusikan beberapa objek Java yang sangat umum dan berapa biaya operasinya menggunakan notasi Big-O. objectissues.blogspot.com/2006/11/...
Nick

Meskipun tidak dalam domain publik, Java Generics and Collections yang sangat baik oleh Maurice Naftalin dan Philip Wadler mencantumkan ikhtisar informasi runtime dalam bab-babnya pada kelas koleksi yang berbeda.
Fabian Steeg

1
Apakah tolok ukur kinerja ini dapat digunakan?
ThreaT

Jawaban:


149

Situs web ini cukup bagus tetapi tidak khusus untuk Java: http://bigocheatsheet.com/ Berikut ini gambar jika tautan ini tidak berfungsi


27
Dan inilah mengapa kami tidak menggunakan URL sebagai jawaban. Dokumen / server itu, sejauh yang saya tahu, tidak lagi tersedia!
Jason Mock

1
@Ben J Links tidak berfungsi lagi
Vikas V

Tautan arsip web sekarang juga rusak.
MikeFHay

Tampaknya URL yang berfungsi baru ditambahkan. Terima kasih telah berusaha, ini sangat membantu.
Tejas C

1
@AndreaZilio LinkedList.remove (Obyek) adalah waktu yang konstan, dengan asumsi Anda sudah tahu tetangga. Jika Anda tidak mengenal tetangga, sekarang saatnya untuk menemukannya terlebih dahulu.
Paul Evans

217

Buku Java Generics and Collections memiliki informasi ini (halaman: 188, 211, 222, 240).

Daftar implementasi:

                      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)

Tetapkan implementasi:

                      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)

Implementasi peta:

                      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)

Implementasi antrian:

                      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)

Bagian bawah javadoc untuk paket java.util berisi beberapa tautan bagus:


3
Anda harus menentukan untuk skenario kasus mana angka-angka itu, misalnya, hapus dari Arraylist dapat mengambil O (n), jika Anda menghapus elemen di tengah atau akhir array.
Popeye

@ Popeye bukankah O biasanya kasus terburuk?
Yassin Hajaj

Seperti yang disebutkan oleh @Popeye, harus ada deskripsi yang jelas tentang kasus apa jawabannya. Kasing dapat berupa kompleksitas rata-rata / terburuk untuk waktu. Sepertinya jawabannya mengacu pada kasus "rata-rata" untuk semua DS.
Yashwin Munsadwala

12

Javadocs dari Sun untuk setiap kelas koleksi umumnya akan memberi tahu Anda apa yang Anda inginkan. HashMap , misalnya:

Implementasi ini memberikan kinerja waktu-konstan untuk operasi dasar (dapatkan dan taruh), dengan asumsi fungsi hash menyebarkan elemen-elemen dengan baik di antara bucket. Iterasi atas tampilan koleksi memerlukan waktu yang sebanding dengan "kapasitas" instance HashMap (jumlah ember) plus ukurannya (jumlah pemetaan nilai kunci).

TreeMap :

Implementasi ini memberikan jaminan log (n) biaya waktu untuk containKey, dapatkan, masukkan dan hapus operasi.

TreeSet :

Implementasi ini memberikan jaminan log (n) biaya waktu untuk operasi dasar (menambah, menghapus, dan memuat).

(penekanan milikku)


Saya tidak setuju dengan bagian HashMap. Saya tahu posisi Sun, tapi ... dapatkan misalnya harus memanggil obj.equals (kunci), yang bisa linier dalam ukuran objek yang terkandung. Pertimbangkan bahwa Anda biasanya harus membaca bidang untuk perbandingan ini. Pengecualian akan berupa bilangan bulat atau string (diinternir) ???
Overflown

Pertama-tama, jika mereka salah, seharusnya tidak terlalu sulit bagi Anda untuk membuat test case yang menyangkal kinerja waktu-konstan? Kedua, jika Anda melihat kode sumber untuk HashMap, itu tidak memanggil equals () terhadap setiap kunci di peta - hanya ketika kode hash sama.
matt b

5
Jika Anda membaca kutipan di atas, ia mengatakan ini adalah waktu konstan "dengan asumsi fungsi hash menyebarkan elemen-elemen dengan baik di antara kotak-kotak". Dari teori CS, tabel hash memiliki operasi waktu yang konstan ketika fungsi hash "baik" (yang terjadi rata-rata), tetapi mungkin memerlukan waktu linier dalam kasus terburuk.
newacct

4
@Overflown - secara teknis, tidak masalah berapa lama obj.equals () mengambil dari perspektif kompleksitas, karena itu hanya bagian dari "konstan" yang terkait dengan jumlah item dalam koleksi.
mikera

6

Orang di atas memberi perbandingan untuk HashMap / HashSet vs. TreeMap / TreeSet.

Saya akan berbicara tentang ArrayList vs. LinkedList:

Daftar Array:

  • O (1) get()
  • diamortisasi O (1) add()
  • jika Anda menyisipkan atau menghapus elemen di tengah menggunakan ListIterator.add()atau Iterator.remove(), itu akan menjadi O (n) untuk menggeser semua elemen berikut

LinkedList:

  • Di) get()
  • O (1) add()
  • jika Anda menyisipkan atau menghapus elemen di tengah menggunakan ListIterator.add()atau Iterator.remove(), itu akan menjadi O (1)

1
if you insert or delete an element in the middle using ListIterator.add() or Iterator.remove(), it will be O(1) Mengapa? pertama kita perlu mencari elemen di tengah, jadi mengapa tidak O (n)?
MyTitle

@ MyTitle: baca lagi. "menggunakan ListIterator.add()atau Iterator.remove()" Kami memiliki iterator.
Newacct
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.