Membaca dokumentasi Java untuk Daftar ADT dikatakan:
Antarmuka Daftar menyediakan empat metode untuk akses posisi (diindeks) ke elemen daftar. Daftar (seperti array Java) berbasis nol. Perhatikan bahwa operasi ini dapat dijalankan dalam waktu yang sebanding dengan nilai indeks untuk beberapa implementasi (kelas LinkedList, misalnya). Jadi, melakukan iterasi terhadap elemen dalam daftar biasanya lebih baik daripada mengindeksnya jika pemanggil tidak mengetahui implementasinya.
Apa sebenarnya artinya ini? Saya tidak mengerti kesimpulan yang diambil.
Jawaban:
Dalam daftar tertaut, setiap elemen memiliki penunjuk ke elemen berikutnya:
Untuk mengakses
item3
, Anda dapat melihat dengan jelas bahwa Anda perlu berjalan dari kepala melalui setiap node sampai Anda mencapai item3, karena Anda tidak dapat melompat secara langsung.Jadi, jika saya ingin mencetak nilai setiap elemen, jika saya menulis ini:
yang terjadi adalah ini:
Ini sangat tidak efisien karena setiap kali Anda mengindeksnya dimulai ulang dari awal daftar dan melewati setiap item. Ini berarti kompleksitas Anda secara efektif
O(N^2)
hanya untuk melintasi daftar!Jika sebaliknya saya melakukan ini:
lalu yang terjadi adalah ini:
semua dalam satu traversal, yaitu
O(N)
.Sekarang, pergi ke implementasi lain
List
yangArrayList
, yang didukung oleh array sederhana. Dalam kasus tersebut, kedua traversal di atas setara, karena larik berdekatan sehingga memungkinkan lompatan acak ke posisi arbitrer.sumber
REVERSE_THRESHOLD
diatur 18 injava.util.Collections
, aneh melihat jawaban yang diberi suara tinggi tanpa komentar.List l = unknownList(); if (l instanceof RandomAccess) /* do indexed loop */ else /* use iterator/foreach */
Jawabannya tersirat di sini:
Daftar tertaut tidak memiliki indeks yang melekat; memanggil
.get(x)
akan membutuhkan implementasi daftar untuk menemukan entri pertama dan memanggil.next()
x-1 kali (untuk O (n) atau akses waktu linier), di mana daftar yang didukung array hanya dapat mengindeks kebackingarray[x]
dalam O (1) atau waktu konstan.Jika Anda melihat JavaDoc untuk
LinkedList
, Anda akan melihat komentarnyasedangkan JavaDoc for
ArrayList
memiliki fileSebuah pertanyaan terkait berjudul "Ringkasan Big-O untuk Kerangka Koleksi Java" memiliki jawaban yang menunjuk ke sumber daya ini, "Koleksi Java JDK6" yang mungkin berguna bagi Anda.
sumber
Meskipun jawaban yang diterima pasti benar, bolehkah saya menunjukkan kekurangan kecil. Mengutip Tudor:
Ini tidak sepenuhnya benar. Sebenarnya, itu
sumber: Designing for Performance, dokumen Google Android
Perhatikan bahwa loop tulisan tangan mengacu pada iterasi yang diindeks. Saya menduga itu karena iterator yang digunakan dengan loop untuk ditingkatkan. Ini menghasilkan kinerja kecil dalam penalti dalam struktur yang didukung oleh array yang berdekatan. Saya juga menduga ini mungkin benar untuk kelas Vektor.
Aturan saya adalah, gunakan loop for yang disempurnakan bila memungkinkan, dan jika Anda benar-benar peduli dengan kinerja, gunakan iterasi terindeks hanya untuk ArrayLists atau Vectors. Dalam kebanyakan kasus, Anda bahkan dapat mengabaikan ini- kompilator mungkin mengoptimalkannya di latar belakang.
Saya hanya ingin menunjukkan bahwa dalam konteks pengembangan di Android, traversal ArrayLists belum tentu setara . Hanya makanan untuk dipikirkan.
sumber
Iterasi daftar dengan offset untuk pencarian, seperti
i
, analog dengan algoritma Shlemiel the painter .Sumber .
Cerita kecil ini dapat mempermudah untuk memahami apa yang terjadi secara internal dan mengapa hal itu sangat tidak efisien.
sumber
Untuk menemukan elemen ke-i dari sebuah
LinkedList
implementasi melewati semua elemen hingga ke-i.Begitu
sumber