Algoritma pengurutan cepat dapat dibagi menjadi langkah-langkah berikut
Identifikasi inden.
Partisi daftar tertaut berdasarkan pivot.
Bagi daftar yang ditautkan secara rekursif menjadi 2 bagian.
Sekarang, jika saya selalu memilih elemen terakhir sebagai pivot, maka mengidentifikasi elemen pivot (langkah 1) membutuhkan waktu .
Setelah mengidentifikasi elemen pivot, kita dapat menyimpan datanya dan membandingkannya dengan semua elemen lain untuk mengidentifikasi titik partisi yang benar (langkah ke-2). Setiap perbandingan akan memakan waktu saat kami menyimpan data pivot dan setiap swap membutuhkan waktu . Jadi secara total dibutuhkan waktu untuk elemen.
Jadi relasi perulangan adalah:
yang merupakan yang sama seperti dalam gabungan gabungan dengan daftar yang ditautkan.
Jadi mengapa penggabungan sortir lebih disukai daripada sortir cepat untuk daftar tertaut?
sumber
Jawaban:
Pola akses memori di Quicksort adalah acak, juga implementasi out-of-the-box di tempat, sehingga menggunakan banyak swap jika sel untuk mencapai hasil yang dipesan.
Pada saat yang sama jenis gabungan adalah eksternal, itu memerlukan array tambahan untuk mengembalikan hasil yang dipesan. Dalam array, ini berarti overhead ruang tambahan, dalam kasus jika daftar tertaut, dimungkinkan untuk menarik nilai dan mulai menggabungkan node. Aksesnya lebih berurutan.
Karena itu, quicksort bukanlah pilihan alami untuk daftar tertaut, sementara penggabungan mengambil keuntungan besar.
Notasi Landau mungkin (kurang lebih, karena Quicksort masih ) setuju, tetapi konstanta jauh lebih tinggi.O ( n2)
Dalam kasus rata-rata kedua algoritma berada di sehingga kasus asimptotiknya sama, tetapi preferensi secara ketat disebabkan oleh konstanta tersembunyi dan terkadang kestabilannya adalah masalah (quicksort secara inheren tidak stabil, mergsort stabil) .O (nlogn )
sumber
Anda dapat dengan cepat menyortir daftar yang ditautkan namun Anda akan sangat terbatas dalam hal pemilihan pivot, membatasi Anda untuk pivot di dekat bagian depan daftar yang buruk untuk input yang hampir diurutkan, kecuali jika Anda ingin mengulang setiap segmen dua kali (satu kali untuk pivot dan satu kali untuk partisi). Dan Anda harus menyimpan setumpuk batas partisi untuk daftar yang masih harus Anda sortir. Tumpukan itu dapat tumbuh ke ketika pemilihan pivot buruk bersama dengan kompleksitas waktu yang berkembang menjadi O ( n 2 ) .O ( n ) O ( n2)
Penggabungan sortir pada daftar tertaut dapat dieksekusi hanya menggunakan ruang tambahan jika Anda mengambil pendekatan bottom-up dengan menghitung di mana batas-batas partisi dan penggabungan yang sesuai.O ( 1 )
Namun menambahkan 64 elemen array pointer Anda dapat menghindari iterasi ekstra dan mengurutkan daftar hingga elemen di O ( 1 ) ruang tambahan tambahan.264 O ( 1 )
Ini adalah algoritma yang digunakan kernel linux untuk menyortir daftar tertautnya. Meskipun dengan beberapa optimasi tambahan seperti mengabaikan
previous
pointer selama semua tapi operasi gabungan terakhir.sumber
Anda dapat menulis semacam penggabungan, partisi semacam, semacam pohon dan membandingkan hasil
Hal ini sangat mudah untuk menulis pohon semacam jika Anda mengizinkan beberapa ruang tambahan
Untuk pohon semacam setiap node dari linked list harus memiliki dua pointer bahkan jika kita semacam tunggal linked list
Dalam daftar link saya lebih suka memasukkan dan menghapus daripada menukar
partisi Hoare hanya dapat dilakukan untuk daftar tertaut ganda
Kode ini memerlukan beberapa perbaikan.
Pertama kita harus membatasi penyimpanan ekstra untuk kebutuhan rekursi,
kemudian kita harus mencoba mengganti rekursi dengan iterasi.
Jika kita ingin meningkatkan algoritma lebih lanjut, kita harus menggunakan pohon self balancing.
sumber
Quicksort
Mungkin saya akan menunjukkan langkah-langkah untuk quicksort
Jika daftar berisi lebih dari satu simpul
sublist pertama sublist berisi node dengan kunci kurang dari kunci pivot
sublist kedua berisi node dengan kunci sama dengan kunci pivot
sublist ketiga berisi node dengan kunci lebih besar dari kunci pivot
Iklan 1.
Jika kita ingin memilih pivot cepat, pilihannya terbatas.
Kita dapat memilih head node atau tail node
. Daftar kita harus memiliki poiner ke node jika kita ingin pivot kita
dapat diakses dengan cepat jika tidak kita harus mencari node
Iklan 2.
Kita dapat menggunakan operasi antrian untuk langkah ini.
Fist we dequeue node dari daftar tertaut asli
membandingkan kuncinya dengan kunci pivot dan enqueue ke sublist yang benar.
Sublist dibuat dari node yang ada dan tidak perlu
mengalokasikan memori untuk node baru
Pointer ke tail tail akan bermanfaat karena operasi antrian
dan penggabungan berjalan lebih cepat dengan kehadiran pointer ini
sumber