Ini adalah pos ulang pertanyaan di cs.SE oleh Janoma . Kredit penuh dan rampasan untuknya atau cs.SE.
Dalam kursus algoritma standar kita diajarkan bahwa quicksort rata-rata adalah O (n log n) dan O (n²) dalam kasus terburuk. Pada saat yang sama, algoritma pengurutan lainnya dipelajari yaitu O (n log n) dalam kasus terburuk (seperti mergesort dan heapsort ), dan bahkan waktu linear dalam kasus terbaik (seperti bubblesort ) tetapi dengan beberapa kebutuhan memori tambahan.
Setelah sekilas melihat beberapa waktu berlari , wajar untuk mengatakan bahwa quicksort tidak seefisien yang lainnya.
Juga, pertimbangkan bahwa siswa belajar dalam kursus pemrograman dasar bahwa rekursi tidak benar-benar baik secara umum karena dapat menggunakan terlalu banyak memori, dll. Oleh karena itu (dan meskipun ini bukan argumen nyata), ini memberikan gagasan bahwa quicksort mungkin tidak sangat bagus karena merupakan algoritma rekursif.
Mengapa, kemudian, apakah quicksort mengungguli algoritma pengurutan lainnya dalam praktek? Apakah itu ada hubungannya dengan struktur data dunia nyata ? Apakah itu ada hubungannya dengan cara memori bekerja di komputer? Saya tahu bahwa beberapa ingatan jauh lebih cepat daripada yang lain, tetapi saya tidak tahu apakah itu alasan sebenarnya untuk kinerja kontra-intuitif ini (bila dibandingkan dengan perkiraan teoritis).
sumber
Jawaban:
Saya tidak akan setuju bahwa quicksort lebih baik daripada algoritma pengurutan lainnya dalam praktiknya.
Untuk sebagian besar tujuan, Timsort - hibrid antara jenis mergesort / penyisipan yang mengeksploitasi fakta bahwa data yang Anda urutkan sering dimulai hampir diurutkan atau diurutkan mundur.
Quicksort yang paling sederhana (tanpa pivot acak) memperlakukan kasus yang berpotensi umum ini sebagai O (N ^ 2) (dikurangi menjadi O (N lg N) dengan pivot acak), sementara TimSort dapat menangani kasus ini dalam O (N).
Menurut tolok ukur ini dalam C # yang membandingkan quicksort bawaan dengan TimSort, Timsort secara signifikan lebih cepat dalam sebagian besar kasus yang diurutkan, dan sedikit lebih cepat dalam kasus data acak dan TimSort menjadi lebih baik jika fungsi perbandingan sangat lambat. Saya belum mengulangi tolok ukur ini dan tidak akan terkejut jika quicksort sedikit mengalahkan TimSort untuk beberapa kombinasi data acak atau jika ada sesuatu yang unik dalam jenis builtin C # (berdasarkan quicksort) yang memperlambatnya. Namun, TimSort memiliki keuntungan yang berbeda ketika data dapat diurutkan sebagian, dan kira-kira sama dengan quicksort dalam hal kecepatan ketika data tidak diurutkan sebagian.
TimSort juga memiliki bonus tambahan untuk menjadi yang stabil, tidak seperti quicksort. Satu-satunya kelemahan TimSort menggunakan memori O (N) versus O (lg N) dalam implementasi (cepat) yang biasa.
sumber
Sortir cepat dianggap lebih cepat karena koefisiennya lebih kecil daripada algoritma lainnya yang diketahui. Tidak ada alasan atau bukti untuk itu, hanya tidak ada algoritma dengan koefisien yang lebih kecil telah ditemukan. Memang benar bahwa algoritma lain juga memiliki waktu O ( n log n ), tetapi di dunia nyata koefisien juga penting.
Perhatikan bahwa untuk jenis penyisipan data kecil (yang dianggap O ( n 2 )) lebih cepat karena sifat fungsi matematika. Ini tergantung pada koefisien spesifik yang bervariasi dari mesin ke mesin. (Pada akhirnya, hanya perakitan yang benar-benar berjalan.) Jadi kadang-kadang hibrida jenis cepat dan jenis penyisipan adalah yang tercepat dalam praktiknya saya pikir.
sumber
Quicksort tidak mengungguli semua algoritma penyortiran lainnya. Misalnya, bottom-up heap sort ( Wegener 2002 ) mengungguli quicksort untuk jumlah data yang masuk akal dan juga merupakan algoritma di tempat. Ini juga mudah diimplementasikan (setidaknya, tidak lebih keras dari beberapa varian quicksort yang dioptimalkan).
Itu tidak begitu terkenal dan Anda tidak menemukannya di banyak buku pelajaran, yang mungkin menjelaskan mengapa itu tidak sepopuler quicksort.
sumber
Anda seharusnya tidak hanya berpusat pada kasus terburuk dan hanya pada kompleksitas waktu. Ini lebih tentang rata-rata daripada yang terburuk, dan ini tentang waktu dan ruang.
Quicksort:
Juga memiliki catatan bahwa notasi O besar tidak memperhitungkan konstanta, tetapi dalam praktiknya itu membuat perbedaan jika algoritma beberapa kali lebih cepat. Θ ( n log n ) berarti, algoritma yang dijalankan dalam K n log ( n ), di mana K adalah konstan. Quicksort adalah algoritma perbandingan-jenis dengan K terendah .
sumber
Quicksort seringkali merupakan pilihan yang baik karena cukup cepat dan cukup cepat serta mudah diimplementasikan.
Jika Anda serius menyortir data dalam jumlah besar dengan sangat cepat maka Anda mungkin lebih baik dengan beberapa variasi pada MergeSort. Ini dapat dibuat untuk mengambil keuntungan dari penyimpanan eksternal, dapat menggunakan beberapa utas atau bahkan proses tetapi tidak sepele terhadap kode.
sumber
Kinerja algoritma yang sebenarnya tergantung pada platform, serta bahasa, kompiler, perhatian programmer terhadap detail implementasi, upaya pengoptimalan spesifik, dan lain-lain. Jadi, "keunggulan faktor konstan" quicksort tidak terlalu terdefinisi dengan baik - ini adalah penilaian subjektif berdasarkan alat yang tersedia saat ini, dan perkiraan kasar "upaya implementasi yang setara" oleh siapa pun yang benar-benar melakukan studi kinerja komparatif .. .
Yang mengatakan, saya percaya quicksort berkinerja baik (untuk input acak) karena sederhana, dan karena struktur rekursifnya relatif ramah terhadap cache. Di sisi lain, karena kasus terburuknya mudah dipicu, setiap penggunaan praktis quicksort harus lebih kompleks daripada deskripsi buku teksnya akan menunjukkan: dengan demikian, versi yang dimodifikasi seperti introsort.
Seiring berjalannya waktu, ketika platform dominan berubah, algoritme yang berbeda dapat memperoleh atau kehilangan keunggulan relatifnya (tidak jelas). Kearifan konvensional tentang kinerja relatif mungkin tertinggal dari perubahan ini, jadi jika Anda benar-benar tidak yakin algoritma mana yang terbaik untuk aplikasi Anda, Anda harus mengimplementasikan keduanya, dan mengujinya.
sumber