Array versus linked-list

200

Mengapa seseorang ingin menggunakan daftar tertaut di atas array?

Pengkodean daftar-tertaut, tidak diragukan lagi, sedikit lebih banyak bekerja daripada menggunakan array dan orang mungkin bertanya-tanya apa yang akan membenarkan upaya tambahan.

Saya pikir penyisipan elemen baru adalah sepele dalam daftar-tertaut tapi itu adalah tugas utama dalam sebuah array. Apakah ada keuntungan lain dari menggunakan daftar tertaut untuk menyimpan satu set data dibandingkan menyimpannya dalam array?

Pertanyaan ini bukan duplikat dari pertanyaan ini karena pertanyaan lain adalah menanyakan secara khusus tentang kelas Java tertentu sementara pertanyaan ini berkaitan dengan struktur data umum.

Onorio Catenacci
sumber
1
Terkait - Kapan menggunakan LinkedList <> di atas ArrayList <>? - Ini Java, tetapi array (ArrayList) dan linked-list mungkin memiliki kinerja yang sama dalam bahasa apa pun.
Bernhard Barker
1
@rootTraveller Sebenarnya pertanyaan itu akan menjadi duplikat dari pertanyaan ini karena pertanyaan saya diposting terlebih dahulu.
Onorio Catenacci

Jawaban:

147
  • Lebih mudah menyimpan data dengan ukuran berbeda di daftar tertaut. Array mengasumsikan setiap elemen berukuran persis sama.
  • Seperti yang Anda sebutkan, daftar yang ditautkan lebih mudah tumbuh secara organik. Ukuran array harus diketahui sebelumnya, atau dibuat ulang saat perlu tumbuh.
  • Mengocok daftar tertaut hanyalah masalah mengubah poin apa menjadi apa. Mengocok array lebih rumit dan / atau membutuhkan lebih banyak memori.
  • Selama iterasi Anda semua terjadi dalam konteks "foreach", Anda tidak kehilangan kinerja dalam iterasi.
Ryan
sumber
19
Bagaimana item dengan ukuran berbeda diperlakukan berbeda? Daftar tertaut baik menggunakan struct tetap dengan bidang berikutnya (membutuhkan ukuran tetap), atau menyimpan pointer ke data di dalam mobil (ukuran variabel OK). Kedua pendekatan sama mudahnya dengan vektor. Hal yang sama untuk pengocokan.
Brian
32
Saya akan mengatakan mengocok array tidak terlalu rumit.
Hugh Allen
23
Jawaban ini salah dan menyesatkan. (Kecuali jika perlu mengetahui ukuran array ketika Anda mendeklarasikannya)
Robert Paulson
35
Tidakkah pengulangan daftar tertaut menjadi lebih lambat karena lokalitas data?
Firas Assaad
6
@Ick, vektor biasanya secara keseluruhan menempatkan ruang yang mereka butuhkan sehingga mereka tidak perlu mengalokasikan ruang baru setiap kali ukurannya meningkat. Hasilnya adalah bahwa vektor biasanya kurang intensif memori, tidak lebih dari daftar tertaut.
Winston Ewert
179

Alasan bagus lainnya adalah bahwa daftar tertaut cocok untuk implementasi multi-utas yang efisien. Alasan untuk ini adalah bahwa perubahan cenderung bersifat lokal - hanya mempengaruhi satu atau dua penunjuk untuk disisipkan dan dihapus pada bagian lokal dari struktur data. Jadi, Anda dapat memiliki banyak utas yang bekerja pada daftar tertaut yang sama. Terlebih lagi, dimungkinkan untuk membuat versi bebas-kunci menggunakan operasi tipe-CAS dan menghindari kunci yang berat sama sekali.

Dengan daftar tertaut, iterator juga dapat melintasi daftar saat modifikasi sedang terjadi. Dalam kasus optimis di mana modifikasi tidak berbenturan, iterator dapat berlanjut tanpa pertengkaran.

Dengan sebuah array, setiap perubahan yang memodifikasi ukuran array cenderung membutuhkan penguncian sebagian besar array dan pada kenyataannya, jarang terjadi hal ini dilakukan tanpa kunci global di seluruh array sehingga modifikasi menjadi penghentian urusan dunia.

Alex Miller
sumber
9
Alex - itu pertimbangan menarik yang tidak akan pernah terpikir olehku. Jawaban yang sangat bagus Saya akan mendukung Anda dua kali jika saya bisa. :-)
Onorio Catenacci
5
Lihatlah daftar lewati (khususnya ConcurrentSkipListMap di Java 6) untuk ide yang baik tentang di mana Anda bisa pergi dengan ini. CSLM adalah peta yang diurutkan dan berbarengan dengan kinerja yang sangat baik. Jauh, jauh lebih baik daripada TreeMap yang disinkronkan. tech.puredanger.com/2007/10/03/skip-lists
Alex Miller
... kecuali itu ConcurrentSkipListMapatau ConcurrentSkipListMapbukan daftar, bahkan jika "Daftar" muncul di suatu tempat atas namanya. Keduanya membutuhkan kunci yang akan diurutkan dan unik. Jika Anda memerlukan List, yaitu struktur data yang memungkinkan elemen duplikat dalam urutan acak, itu tidak cocok dan Anda harus berusaha keras untuk membuat struktur data seperti LinkedListhal yang dapat diperbarui secara bersamaan. Jika Anda hanya perlu antrian atau deque bersamaan, ya, bahkan ada contoh yang ada, tetapi konkuren List... Saya tidak yakin bahwa ini bahkan mungkin.
Holger
128

Wikipedia memiliki bagian yang sangat bagus tentang perbedaannya.

Daftar tertaut memiliki beberapa keunggulan dibandingkan array. Elemen dapat dimasukkan ke dalam daftar tertaut tanpa batas, sementara array pada akhirnya akan terisi atau perlu diubah ukurannya, sebuah operasi mahal yang bahkan mungkin tidak dapat dilakukan jika memori terfragmentasi. Demikian pula, sebuah array dari mana banyak elemen dihapus mungkin menjadi kosong kosong atau perlu dibuat lebih kecil.

Di sisi lain, array memungkinkan akses acak, sementara daftar tertaut hanya memungkinkan akses berurutan ke elemen. Daftar yang terhubung sendiri, pada kenyataannya, hanya dapat dilintasi satu arah. Hal ini membuat daftar yang ditautkan tidak cocok untuk aplikasi yang berguna untuk mencari elemen berdasarkan indeksnya dengan cepat, seperti heapsort. Akses berurutan pada array juga lebih cepat daripada pada daftar tertaut pada banyak mesin karena lokalitas referensi dan cache data. Daftar tertaut hampir tidak mendapat manfaat dari cache.

Kerugian lain dari daftar tertaut adalah penyimpanan tambahan yang diperlukan untuk referensi, yang sering membuatnya tidak praktis untuk daftar item data kecil seperti karakter atau nilai boolean. Ini juga bisa lambat, dan dengan pengalokasi naif, boros, untuk mengalokasikan memori secara terpisah untuk setiap elemen baru, masalah yang umumnya diselesaikan dengan menggunakan kumpulan memori.

http://en.wikipedia.org/wiki/Linked_list

Jonas Klemming
sumber
4
Ini jawaban yang sempurna. Secara ringkas menjelaskan kelebihan dan kekurangan keduanya.
Rick
terima kasih)) sangat sederhana tapi saya belum melihatnya di wiki)
Timur Fayzrakhmanov
58

Saya akan menambahkan yang lain - daftar dapat bertindak sebagai struktur data yang berfungsi murni .

Misalnya, Anda dapat memiliki daftar yang sama sekali berbeda berbagi bagian akhir yang sama

a = (1 2 3 4, ....)
b = (4 3 2 1 1 2 3 4 ...)
c = (3 4 ...)

yaitu:

b = 4 -> 3 -> 2 -> 1 -> a
c = a.next.next  

tanpa harus menyalin data yang ditunjuk oleh ake bdan c.

Inilah sebabnya mengapa mereka sangat populer dalam bahasa fungsional, yang menggunakan variabel tidak berubah - prependdan tailoperasi dapat terjadi secara bebas tanpa harus menyalin data asli - fitur yang sangat penting ketika Anda memperlakukan data sebagai tidak dapat diubah.

Brian
sumber
4
Namun pertimbangan lain yang sangat menarik yang tidak akan pernah saya pikirkan. Terima kasih.
Onorio Catenacci
Bagaimana saya bisa melakukan ini dengan python?
overexchange
29

Selain memasukkan ke tengah daftar menjadi lebih mudah - juga jauh lebih mudah untuk menghapus dari tengah daftar yang ditautkan daripada array.

Tapi sejujurnya, saya tidak pernah menggunakan daftar tertaut. Setiap kali saya membutuhkan penyisipan dan penghapusan cepat, saya juga membutuhkan pencarian cepat, jadi saya pergi ke HashSet atau Kamus.

Tom Ritter
sumber
2
Sangat benar, penyisipan dan penghapusan muncul setelah mencari sebagian besar waktu, jadi perlu mempertimbangkan jumlah kompleksitas waktu juga.
MA Hossain Tonu
28

Menggabungkan dua daftar tertaut (terutama dua daftar tertaut dua kali lipat) jauh lebih cepat daripada menggabungkan dua array (dengan asumsi penggabungan itu merusak). Yang pertama mengambil O (1), yang terakhir mengambil O (n).

EDIT: Untuk memperjelas, maksud saya "penggabungan" di sini dalam arti tidak tertata, bukan seperti dalam penggabungan. Mungkin "menyatukan" akan menjadi kata yang lebih baik.

rampion
sumber
2
Hanya jika Anda hanya menambahkan satu daftar ke yang lain. Jika Anda benar-benar menggabungkan dua daftar yang disortir maka akan membutuhkan log lebih dari O (1)
Herms
3
@ Manusia, tetapi Anda dapat menggabungkan dua daftar tertaut yang disortir tanpa mengalokasikan memori tambahan, hanya melintasi kedua daftar dan mengatur pointer dengan tepat. Menggabungkan dua array biasanya membutuhkan setidaknya satu array tambahan.
Paul Tomblin
1
Ya, menggabungkan daftar lebih hemat memori, tapi itu bukan yang saya komentari. Mengatakan menggabungkan daftar tertaut adalah O (1) sangat menyesatkan tanpa klarifikasi kasus.
Herms
@Rumah daftar penggabungan tidak lebih efisien memori daripada menggabungkan array di bawah model data yang masuk akal.
Alexei Averchenko
2
Alexei Averchenko: Menggabungkan dua daftar, atau bahkan menggabungkan dua daftar yang diurutkan, dapat dilakukan di tempat, dengan memori O (1). Menggabungkan dua array membutuhkan O (n) memori tentu, kecuali array sudah bersebelahan dalam memori. Saya pikir poin yang Anda tuju adalah bahwa di mana daftar elemen n dan array elemen keduanya mengambil O (n) memori, tetapi koefisien lebih tinggi untuk daftar tertaut.
rampion
17

Argumen yang secara luas tidak dihargai untuk ArrayList dan terhadap LinkedList adalah bahwa LinkedLists tidak nyaman saat melakukan debugging . Waktu yang dihabiskan oleh pengembang pemeliharaan untuk memahami program, misalnya untuk menemukan bug, meningkat dan IMHO kadang-kadang tidak membenarkan nanodetik dalam peningkatan kinerja atau byte dalam konsumsi memori dalam aplikasi perusahaan. Terkadang (well, tentu saja itu tergantung pada jenis aplikasi), lebih baik membuang beberapa byte tetapi memiliki aplikasi yang lebih mudah dirawat atau lebih mudah dipahami.

Misalnya, di lingkungan Java dan menggunakan Eclipse debugger, debugging ArrayList akan mengungkapkan struktur yang sangat mudah dipahami:

arrayList   ArrayList<String>
  elementData   Object[]
    [0] Object  "Foo"
    [1] Object  "Foo"
    [2] Object  "Foo"
    [3] Object  "Foo"
    [4] Object  "Foo"
    ...

Di sisi lain, menonton konten LinkedList dan menemukan objek tertentu menjadi mimpi buruk mengklik Expand-The-Tree, belum lagi overhead kognitif yang diperlukan untuk menyaring internal LinkedList:

linkedList  LinkedList<String>
    header  LinkedList$Entry<E>
        element E
        next    LinkedList$Entry<E>
            element E   "Foo"
            next    LinkedList$Entry<E>
                element E   "Foo"
                next    LinkedList$Entry<E>
                    element E   "Foo"
                    next    LinkedList$Entry<E>
                    previous    LinkedList$Entry<E>
                    ...
                previous    LinkedList$Entry<E>
            previous    LinkedList$Entry<E>
        previous    LinkedList$Entry<E>
mhaller
sumber
17

Pertama-tama, di C ++ linked-list seharusnya tidak lebih banyak kesulitan untuk dikerjakan daripada sebuah array. Anda dapat menggunakan std :: list atau daftar penambah boost untuk daftar tertaut. Masalah utama dengan daftar tertaut vs array adalah ruang tambahan yang diperlukan untuk pointer dan akses acak yang mengerikan. Anda harus menggunakan daftar tertaut jika Anda

  • Anda tidak perlu akses acak ke data
  • Anda akan menambahkan / menghapus elemen, terutama di bagian tengah daftar
David Nehme
sumber
14

Bagi saya itu seperti ini,

  1. Mengakses

    • Linked Linked hanya memungkinkan akses berurutan ke elemen. Dengan demikian kompleksitas algoritmik adalah urutan O (n)
    • Array memungkinkan akses acak ke elemen-elemennya dan karenanya kompleksitasnya adalah urutan O (1)
  2. Penyimpanan

    • Daftar tertaut memerlukan penyimpanan tambahan untuk referensi. Ini membuatnya tidak praktis untuk daftar item data kecil seperti karakter atau nilai boolean.
    • Array tidak perlu penyimpanan tambahan untuk menunjuk ke item data berikutnya. Setiap elemen dapat diakses melalui indeks.
  3. Ukuran

    • Ukuran daftar Linked bersifat dinamis.
    • Ukuran array terbatas pada deklarasi.
  4. Penyisipan / Penghapusan

    • Elemen dapat dimasukkan dan dihapus dalam daftar tertaut tanpa batas.
    • Penyisipan / Penghapusan nilai dalam array sangat mahal. Itu membutuhkan realokasi memori.
Sulman
sumber
Anda memiliki 2 angka 2, dan 2 angka 3 :)
Hengameh
Kita dapat mendeklarasikan array kosong dan kemudian menambahkan data seperti yang diperlukan. Bagaimana itu membuat ukuran tetap?
HebleV
11

Dua hal:

Coding daftar tertaut adalah, tidak diragukan lagi, sedikit lebih banyak pekerjaan daripada menggunakan array dan dia bertanya-tanya apa yang akan membenarkan upaya tambahan.

Jangan pernah kode kode daftar tertaut saat menggunakan C ++. Cukup gunakan STL. Betapa sulitnya untuk mengimplementasikan seharusnya tidak pernah menjadi alasan untuk memilih satu struktur data daripada yang lain karena sebagian besar sudah diterapkan di sana.

Adapun perbedaan aktual antara array dan daftar tertaut, hal besar bagi saya adalah bagaimana Anda berencana menggunakan struktur. Saya akan menggunakan vektor istilah karena itulah istilah untuk array yang dapat diubah ukurannya dalam C ++.

Pengindeksan ke daftar tertaut lambat karena Anda harus melintasi daftar untuk mendapatkan indeks yang diberikan, sementara vektor bersebelahan dalam memori dan Anda bisa sampai di sana menggunakan pointer matematika.

Menambahkan ke akhir atau awal daftar tertaut itu mudah, karena Anda hanya perlu memperbarui satu tautan, di mana dalam vektor Anda mungkin harus mengubah ukuran dan menyalin isinya.

Menghapus item dari daftar itu mudah, karena Anda hanya perlu memutuskan sepasang tautan dan kemudian memasangnya kembali. Menghapus item dari vektor bisa lebih cepat atau lebih lambat, tergantung apakah Anda peduli dengan pesanan. Menukar item terakhir dari atas item yang ingin Anda hapus lebih cepat, sementara menggeser semuanya setelah lebih lambat tetapi tetap memesan.

bradtgmurray
sumber
Seperti yang saya katakan pada seseorang di atas, saya hanya mencoba mengaitkan pertanyaannya dengan cara saya. Saya tidak akan pernah menggunakan array (atau roll-my-own linked list) di C ++ - saya akan menggunakan versi STL dari keduanya.
Onorio Catenacci
10

Eric Lippert baru-baru ini memposting di salah satu alasan mengapa array harus digunakan secara konservatif.

Rik
sumber
2
Memang posting yang bagus, tetapi tidak relevan dalam daftar tertaut versus diskusi array.
Robert Paulson
2
Saya menyarankan bahwa banyak artikel Eric relevan, karena membahas kelemahan array dan kelebihan Daftar, terlepas dari implementasi daftar.
Bevan
8

Penyisipan dan penghapusan cepat memang argumen terbaik untuk daftar tertaut. Jika struktur Anda tumbuh secara dinamis dan akses waktu konstan ke elemen apa pun tidak diperlukan (seperti tumpukan dinamis dan antrian), daftar tertaut adalah pilihan yang baik.

Firas Assaad
sumber
7

Ini yang cepat: Penghapusan item lebih cepat.

itsmatt
sumber
7

Linked-list sangat berguna ketika koleksi terus tumbuh & menyusut. Misalnya, sulit membayangkan mencoba menerapkan Antrian (tambahkan ke akhir, hapus dari depan) menggunakan sebuah array - Anda akan menghabiskan seluruh waktu Anda untuk mengubah segalanya. Di sisi lain, itu sepele dengan daftar-tertaut.

James Curran
sumber
4
Anda dapat memiliki antrian berbasis array tanpa terlalu banyak pekerjaan yang masih cepat / efisien. Anda hanya perlu melacak indeks mana yang "kepala" dan mana yang "ekor". Ini berfungsi cukup baik jika Anda memerlukan antrian ukuran tetap (misalnya, buffer keyboard di kernel).
Herms
3
Dan disebut "buffer melingkar", jika Anda ingin mencarinya di referensi algoritma favorit Anda.
Steve Jessop
7

Selain menambah dan menghapus dari tengah daftar, saya lebih suka daftar tertaut karena mereka dapat tumbuh dan menyusut secara dinamis.

Vasil
sumber
6
Vektor (= pada dasarnya array) dapat melakukannya juga dan biaya diamortisasi untuk mereka biasanya lebih kecil dari itu untuk daftar karena masalah referensi lokalitas.
Konrad Rudolph
7

Tidak ada yang pernah mengkode daftar tertaut mereka lagi. Itu konyol. Premis bahwa menggunakan daftar tertaut membutuhkan lebih banyak kode sama sekali salah.

Saat ini, membuat daftar tertaut hanyalah latihan untuk siswa sehingga mereka dapat memahami konsep tersebut. Sebagai gantinya, semua orang menggunakan daftar yang dibuat sebelumnya. Dalam C ++, berdasarkan pada deskripsi di pertanyaan kami, itu mungkin berarti vektor stl ( #include <vector>).

Oleh karena itu, memilih daftar yang ditautkan vs sebuah array sepenuhnya tentang menimbang karakteristik yang berbeda dari setiap struktur relatif terhadap kebutuhan aplikasi Anda. Mengatasi beban pemrograman tambahan harus memiliki dampak nol pada keputusan.

Joel Coehoorn
sumber
2
Er..umm .. Std :: vector adalah array, bukan daftar yang ditautkan. Daftar tertaut standar adalah, yah, std :: daftar.
James Curran
1
ya, tapi saya pikir vektor lebih dekat dengan apa yang diminta oleh op- pengganti array dinamis.
Joel Coehoorn
@ Joel, saya hanya mencoba mengaitkan pertanyaan seperti yang diajukan kepada saya oleh orang ini yang mencoba belajar C ++. Saya tidak akan repot-repot dengan pengkodean daftar tertaut saya sendiri, tetapi begitulah ia bertanya kepada saya. :-)
Onorio Catenacci
Dalam lingkungan terbatas memori (mikrokontroler) yang ada kompiler kustom, tidak semua bahasa (misalnya, wadah di C ++) diimplementasikan. Jadi mungkin Anda harus membuat kode daftar tertaut Anda sendiri. nongnu.org/avr-libc/user-manual/FAQ.html#faq_cplusplus
Minh Tran
6

Ini benar-benar masalah efisiensi, overhead untuk memasukkan, menghapus atau memindahkan (di mana Anda tidak hanya bertukar) elemen dalam daftar tertaut minimal, yaitu operasi itu sendiri adalah O (1), ayat O (n) untuk sebuah array. Ini dapat membuat perbedaan yang signifikan jika Anda banyak beroperasi pada daftar data. Anda memilih tipe data Anda berdasarkan pada bagaimana Anda akan beroperasi pada mereka dan memilih yang paling efisien untuk algoritma yang Anda gunakan.

Steve Baker
sumber
6

Array masuk akal di mana jumlah item yang tepat akan diketahui, dan di mana pencarian berdasarkan indeks masuk akal. Misalnya, jika saya ingin menyimpan keadaan yang tepat dari output video saya pada saat tertentu tanpa kompresi saya mungkin akan menggunakan array ukuran [1024] [768]. Ini akan memberi saya apa yang saya butuhkan, dan daftar akan jauh lebih lambat untuk mendapatkan nilai piksel yang diberikan. Di tempat-tempat di mana array tidak masuk akal, biasanya ada tipe data yang lebih baik daripada daftar untuk menangani data secara efektif.

tloach
sumber
6

Array Vs Linked List:

  1. Alokasi memori array terkadang akan gagal karena memori yang terfragmentasi.
  2. Caching lebih baik dalam Array karena semua elemen dialokasikan ruang memori yang berdekatan.
  3. Pengkodean lebih kompleks dari pada Array.
  4. Tidak ada batasan ukuran pada Daftar Tertaut, tidak seperti Array
  5. Penyisipan / Penghapusan lebih cepat di Daftar Tertaut dan akses lebih cepat di Array.
  6. Linked List lebih baik dari sudut pandang multi-threading.
AKS
sumber
-1: Semua ini perlu dibuktikan, tidak hanya disebutkan.
John Saunders
Setiap poin sudah dijelaskan dalam jawaban di atas. Menjadi seorang latecomer saya tidak punya pilihan lain selain enumerasi. BTW, yang mana yang ingin kamu jelaskan?
AKS
Jika sudah dijelaskan, mengapa Anda menjawab?
John Saunders
2
Sehingga itu akan memberi Anda pandangan ringkasan diskusi. Dan saya suka jenis jawaban seperti itu sehingga saya tidak perlu membaca penjelasan yang sama lagi dan lagi. Dan saya melakukannya untuk orang-orang yang memiliki gaya berpikir yang sama dengan saya. Ppl yang berbeda memiliki gaya yang berbeda. Tidak ada yang baru.
AKS
3

karena array bersifat statis, oleh karena itu semua operasi seperti alokasi memori hanya terjadi pada saat kompilasi. Jadi prosesor harus mengurangi upaya pada saat runtime.

debayan
sumber
3

Misalkan Anda memiliki set yang dipesan, yang juga ingin Anda modifikasi dengan menambahkan dan menghapus elemen. Selanjutnya, Anda membutuhkan kemampuan untuk mempertahankan referensi ke suatu elemen sedemikian rupa sehingga nantinya Anda bisa mendapatkan elemen sebelumnya atau berikutnya. Misalnya, daftar tugas atau kumpulan paragraf dalam sebuah buku.

Pertama-tama kita harus mencatat bahwa jika Anda ingin mempertahankan referensi ke objek di luar set itu sendiri, Anda mungkin akan berakhir menyimpan pointer dalam array, daripada menyimpan objek itu sendiri. Kalau tidak, Anda tidak akan bisa memasukkan ke dalam array - jika objek tertanam ke dalam array mereka akan bergerak selama penyisipan dan setiap pointer ke mereka akan menjadi tidak valid. Hal yang sama berlaku untuk indeks array.

Masalah pertama Anda, seperti yang telah Anda catat sendiri, adalah daftar yang terhubung dengan penyisipan memungkinkan penyisipan dalam O (1), tetapi sebuah array umumnya membutuhkan O (n). Masalah ini sebagian dapat diatasi - dimungkinkan untuk membuat struktur data yang memberikan antarmuka akses by-ordinal seperti array di mana baik membaca dan menulis, paling buruk, logaritmik.

Masalah kedua Anda, dan lebih parah adalah bahwa elemen yang diberikan menemukan elemen berikutnya adalah O (n). Jika set tidak diubah, Anda bisa mempertahankan indeks elemen sebagai referensi alih-alih pointer sehingga membuat operasi find-next O (1), tetapi karena yang Anda miliki hanyalah pointer ke objek itu sendiri dan tidak mungkin untuk menentukan indeks saat ini dalam array selain dengan memindai seluruh "array". Ini adalah masalah yang tidak dapat diatasi untuk array - bahkan jika Anda dapat mengoptimalkan penyisipan, tidak ada yang dapat Anda lakukan untuk mengoptimalkan operasi tipe find-next.

DenNukem
sumber
Bisakah Anda jelaskan ini: "adalah mungkin untuk membuat struktur data yang memberikan antarmuka akses by-ordinal seperti array di mana baik membaca dan menulis, paling buruk, logaritmik."
Hengameh
1
Ada beberapa hal di Wikipedia di bawah bagian Dynamic Array / Vriants. Namun, itu tidak seperti yang ada dalam pikiran saya ... Bayangkan struktur seperti pohon b + dengan halaman tetapi tanpa kunci, sebaliknya setiap halaman perantara mengingat berapa banyak elemen yang ada di setiap sub-halaman, sementara halaman daun hanya memegang elemen dalam array kecil. Saat memasukkan elemen ke halaman daun Anda harus memindahkan ~ setengah halaman untuk membuat ruang, lalu naik dan memperbarui jumlah item pada semua halaman leluhur. Saat mencari elemen #N, cukup tambahkan jumlah item halaman bawahan sampai Anda melewati N, dan kemudian turun ke subtree itu
DenNukem
3

Dalam sebuah array Anda memiliki hak istimewa untuk mengakses elemen apa pun dalam waktu O (1). Jadi itu cocok untuk operasi seperti Pencarian biner, Pengurutan cepat, dll. Daftar tertaut di sisi lain cocok untuk penghapusan penyisipan seperti pada waktu O (1). Keduanya memiliki kelebihan maupun kekurangan dan lebih memilih satu daripada yang lainnya bermuara pada apa yang ingin Anda terapkan.

- Pertanyaan yang lebih besar adalah bisakah kita memiliki hibrida keduanya. Sesuatu seperti apa yang python dan perl terapkan sebagai daftar.

pranjal
sumber
3

Daftar Tertaut

Ini lebih disukai ketika menyangkut penyisipan! Pada dasarnya apa yang dilakukan adalah berurusan dengan pointer

1 -> 3 -> 4

Sisipkan (2)

1 ........ 3 ...... 4
..... 2

Akhirnya

1 -> 2 -> 3 -> 4

Satu panah dari 2 poin di 3 dan panah 1 poin di 2

Sederhana!

Tapi dari Array

| 1 | 3 | 4 |

Sisipkan (2) | 1 | 3 | | 4 | | 1 | | 3 | 4 | | 1 | 2 | 3 | 4 |

Yah siapa pun dapat memvisualisasikan perbedaannya! Hanya untuk 4 indeks kami melakukan 3 langkah

Bagaimana jika panjang array satu juta lalu? Apakah array efisien? Jawabannya adalah tidak! :)

Hal yang sama berlaku untuk penghapusan! Di Linked List kita cukup menggunakan pointer dan membatalkan elemen dan selanjutnya di kelas objek! Tetapi untuk array, kita perlu melakukan shiftLeft ()

Semoga itu bisa membantu! :)

Farah Nazifa
sumber
3

Linked List lebih merupakan overhead untuk mempertahankan daripada array, juga membutuhkan penyimpanan memori tambahan semua poin ini disetujui. Tetapi ada beberapa hal yang tidak dapat dilakukan array. Dalam banyak kasus misalkan Anda menginginkan array dengan panjang 10 ^ 9 Anda tidak bisa mendapatkannya karena mendapatkan satu lokasi memori kontinu harus ada di sana. Daftar tertaut dapat menjadi penyelamat di sini.

Misalkan Anda ingin menyimpan banyak hal dengan data maka mereka dapat dengan mudah diperluas dalam daftar tertaut.

Wadah STL biasanya memiliki implementasi daftar terkait di belakang layar.

iec2011007
sumber
3

1- Daftar tertaut adalah struktur data dinamis sehingga dapat tumbuh dan menyusut pada saat runtime dengan mengalokasikan dan membatalkan alokasi memori. Jadi tidak perlu memberikan ukuran awal dari daftar tertaut. Penyisipan dan penghapusan node sangat mudah.

2 - ukuran daftar tertaut dapat meningkat atau menurun pada saat dijalankan sehingga tidak ada pemborosan memori. Dalam kasus array, ada banyak pemborosan memori, seperti jika kita mendeklarasikan array ukuran 10 dan menyimpan hanya 6 elemen di dalamnya maka ruang 4 elemen terbuang sia-sia. Tidak ada masalah dalam daftar tertaut karena memori hanya dialokasikan bila diperlukan.

3- Struktur data seperti tumpukan dan antrian dapat dengan mudah diimplementasikan menggunakan daftar tertaut.

Ayman Amjad
sumber
2

Satu-satunya alasan untuk menggunakan daftar tertaut adalah memasukkan elemen itu mudah (menghapus juga).

Disadvatige bisa jadi bahwa pointer mengambil banyak ruang.

Dan tentang pengkodean itu lebih sulit: Biasanya Anda tidak perlu daftar kode tertaut (atau hanya sekali) mereka dimasukkan dalam STL dan tidak begitu rumit jika Anda masih harus melakukannya.

pengguna15453
sumber
2
Pointer membutuhkan banyak ruang? Tidak juga. Jika Anda menyimpan daftar boolean yang ditautkan, maka tentu saja, persentase bijaksana pointer membutuhkan banyak ruang. Tetapi jika Anda menyimpan objek kompleks (yang umumnya terjadi) maka pointer mungkin akan diabaikan.
Herms
lupa senyum :) Tapi bilang 'bisa' tidak 'adalah'.
user15453
1

saya juga berpikir bahwa daftar tautan lebih baik daripada array. karena kami melakukan traverse di daftar tautan tetapi tidak di array

iram Arshad
sumber
1

Bergantung pada bahasa Anda, beberapa kelemahan dan kelebihan ini dapat dipertimbangkan:

Bahasa Pemrograman C : Saat menggunakan daftar yang ditautkan (biasanya melalui pointer pointer), pertimbangan khusus harus dipastikan bahwa Anda tidak membocorkan memori. Seperti yang disebutkan sebelumnya, daftar tertaut mudah untuk diacak, karena semua yang dilakukan adalah mengubah pointer, tetapi apakah kita akan ingat untuk membebaskan semuanya?

Java : Java memiliki pengumpulan sampah otomatis, jadi memori yang bocor tidak akan menjadi masalah, tetapi disembunyikan dari pemrogram tingkat tinggi adalah detail implementasi dari apa itu daftar tertaut. Metode seperti menghapus simpul dari tengah daftar lebih rumit dari prosedur daripada yang diharapkan oleh beberapa pengguna bahasa.

SetSlapShot
sumber
1

Mengapa daftar yang ditautkan melalui array? Seperti yang telah dikatakan, kecepatan penyisipan dan penghapusan yang lebih besar

Tapi mungkin kita tidak harus hidup dengan batas baik, dan mendapatkan yang terbaik dari keduanya, pada saat yang sama ... eh?

Untuk penghapusan array, Anda dapat menggunakan byte 'Dihapus', untuk mewakili fakta bahwa sebuah baris telah dihapus, sehingga pengikatan ulang array tidak lagi diperlukan. Untuk meringankan beban penyisipan, atau mengubah data dengan cepat, gunakan daftar tertaut untuk itu. Kemudian ketika merujuk pada mereka, minta logika Anda untuk mencari yang pertama, lalu yang lainnya. Jadi, menggunakannya dalam kombinasi memberi Anda yang terbaik dari keduanya.

Jika Anda memiliki array yang sangat besar, Anda bisa menggabungkannya dengan yang lain, array yang jauh lebih kecil atau daftar tertaut di mana yang lebih kecil menampung 20, 50, 100 item yang paling terakhir digunakan. Jika yang dibutuhkan tidak ada dalam daftar atau array yang lebih pendek, Anda pergi ke array besar. Jika ditemukan di sana, Anda kemudian dapat menambahkannya ke daftar / larik yang lebih kecil dengan anggapan bahwa 'hal-hal yang paling baru digunakan paling mungkin untuk digunakan kembali' (dan ya, mungkin menabrak barang yang paling terakhir digunakan dari daftar). Yang benar dalam banyak kasus dan memecahkan masalah yang saya harus atasi dalam modul pemeriksaan izin .ASP keamanan, dengan mudah, elegan, dan kecepatan mengesankan.

Juan Carlos
sumber
1

Sementara banyak dari Anda telah menyentuh adv./dis utama dari daftar terkait array, sebagian besar perbandingan adalah bagaimana satu lebih baik / lebih buruk daripada yang lain. Anda dapat melakukan akses acak dalam array tetapi tidak mungkin dalam daftar tertaut dan lainnya. Namun, ini dengan asumsi daftar tautan dan larik akan diterapkan dalam aplikasi serupa. Namun jawaban yang benar adalah bagaimana daftar tautan akan lebih disukai daripada array dan sebaliknya dalam penyebaran aplikasi tertentu. Misalkan Anda ingin mengimplementasikan aplikasi kamus, apa yang akan Anda gunakan? Array: mmm itu akan memungkinkan pengambilan mudah melalui pencarian biner dan algo pencarian lainnya .. tapi mari kita pikirkan bagaimana daftar tautan bisa lebih baik .. Katakanlah Anda ingin mencari "Gumpalan" dalam kamus. Apakah masuk akal untuk memiliki daftar tautan A-> B-> C-> D ---->

A -> B -> C -> ...Z
|    |    |
|    |    [Cat, Cave]
|    [Banana, Blob]
[Adam, Apple]

Sekarang apakah pendekatan di atas lebih baik atau susunan datar [Adam, Apple, Banana, Blob, Cat, Cave]? Apakah mungkin dengan array? Jadi keuntungan utama dari daftar tautan adalah Anda dapat memiliki elemen tidak hanya menunjuk ke elemen berikutnya tetapi juga ke beberapa daftar tautan / array / heap / atau lokasi memori lainnya. Array adalah satu memori datar datar yang diiris menjadi ukuran blok elemen yang akan disimpannya. Daftar tautan di sisi lain adalah bongkahan unit memori non-darurat (dapat ukuran apa saja dan dapat menyimpan apa saja) dan menunjuk ke masing-masing selain yang Anda inginkan. Demikian pula katakanlah Anda sedang membuat drive USB. Sekarang apakah Anda ingin file disimpan sebagai array atau daftar tautan? Saya pikir Anda mendapatkan ide tentang apa yang saya tunjukkan :)

Vikalp Veer
sumber