Jadi pada dasarnya, Anda ingin tahu apakah ada algoritma pengurutan yang tidak akan menurun dari kasus rata-rata jika diberi fungsi bandingkan yang mirip dengan:
int Compare(object a, object b) { return Random.Next(-1,1); }
... di mana Random.Next () adalah beberapa metode yang akan menghasilkan bilangan bulat yang dihasilkan secara acak antara batas bawah dan atas inklusif yang ditentukan.
Jawabannya sebenarnya adalah bahwa sebagian besar algoritma pengurutan dasar akan bekerja sesuai dengan kasus rata-rata mereka, karena mereka mematuhi setidaknya satu dari dua kondisi berikut:
- Perbandingan antara dua elemen unik tidak pernah dilakukan dua kali dalam pengurutan, dan / atau
- Dalam setiap iterasi dari jenis, posisi yang benar dari setidaknya satu elemen ditentukan dan elemen tersebut tidak pernah dibandingkan lagi.
Misalnya, SelectionSort beralih melalui sub-daftar elemen yang tidak disortir, menemukan elemen "paling sedikit" dan / atau "terbesar" (dengan membandingkan masing-masing dengan yang terbesar sejauh ini), menempatkannya pada posisi dan pengulangan yang benar. Akibatnya, bahkan dengan pembanding non-deterministik, pada akhir setiap iterasi algoritma akan menemukan nilai yang dianggap paling atau paling besar, menukarnya dengan elemen di posisi yang ia coba untuk menentukan, dan tidak pernah mempertimbangkan elemen itu lagi, sehingga mematuhi Kondisi 2. Namun, A dan B dapat dibandingkan beberapa kali selama proses ini (sebagai contoh paling ekstrim, pertimbangkan beberapa lintasan SelectionSort pada array yang diurutkan dalam urutan terbalik) sehingga melanggar Kondisi 1 .
MergeSort mematuhi Kondisi 1 tetapi tidak 2; karena sub-array digabung, elemen-elemen dalam sub-array yang sama (di sisi kiri atau kanan) tidak dibandingkan satu sama lain karena telah ditentukan bahwa elemen-elemen di sisi array tersebut berada dalam urutan di antara mereka sendiri; algoritme hanya membandingkan elemen yang paling tidak dihapus dari masing-masing subarray dengan yang lain untuk menentukan mana yang lebih rendah dan harus masuk berikutnya dalam daftar gabungan. Ini berarti bahwa setiap dua objek unik A dan B akan dibandingkan satu sama lain maksimum satu kali, tetapi indeks "final" elemen apa pun yang diberikan dalam koleksi lengkap tidak diketahui hingga algoritme selesai.
InsertionSort hanya mematuhi Persyaratan 1 meskipun strategi keseluruhan dan kompleksitasnya lebih mirip dengan SelectionSort. Setiap elemen yang tidak disortir dibandingkan dengan elemen yang diurutkan, terbesar-pertama, hingga ditemukan lebih sedikit dari elemen yang sedang diperiksa. elemen dimasukkan pada titik itu, dan kemudian elemen berikutnya dipertimbangkan. Hasilnya adalah bahwa urutan relatif dari setiap A dan B ditentukan oleh satu perbandingan, dan perbandingan lebih lanjut antara A dan B tidak pernah dilakukan, tetapi posisi akhir dari setiap elemen tidak dapat diketahui sampai semua elemen dipertimbangkan.
QuickSort mematuhi keduanyaKondisi. Di setiap tingkat, pivot dipilih dan disusun sedemikian rupa sehingga sisi "kiri" mengandung elemen lebih sedikit dari pivot dan sisi "kanan" mengandung elemen yang lebih besar daripada pivot. Hasil level tersebut adalah QuickSort (kiri) + pivot + QuickSort (kanan) yang pada dasarnya berarti posisi elemen pivot diketahui (satu indeks lebih besar dari panjang sisi kiri), pivot tidak pernah dibandingkan dengan elemen lain setelah dipilih sebagai pivot (mungkin telah dibandingkan dengan elemen pivot sebelumnya, tetapi elemen-elemen tersebut juga diketahui dan tidak termasuk dalam sub-susun apa pun), DAN setiap A dan B yang berakhir pada sisi berlawanan dari pivot tidak pernah dibandingkan. Dalam sebagian besar implementasi QuickSort murni, casing dasar adalah satu elemen, di mana titik indeks saat ini adalah indeks akhir dan tidak ada perbandingan lebih lanjut yang dibuat.
Satu-satunya jenis komparatif yang dapat saya pikirkan yang tidak mematuhi kedua kondisi ini adalah BubbleSort yang tidak dioptimalkan. Jika pengurutan tidak menerima bahwa elemen X terbesar berada di tempat yang tepat setelah menjalankan X pass, dan / atau menggunakan pass "periksa ulang" untuk memverifikasi daftar diurutkan, pengurutan hanya akan dianggap "selesai" ketika pembanding acak telah kembali -1 atau 0 untuk setiap dua elemen yang berdekatan dalam daftar selama lulus dan dengan demikian tidak ada swap dilakukan (sebuah acara yang, jika benar-benar acak, akan terjadi dengan probabilitas ( 2 / 3 )N- 1 , karena relatif daftar kecil 25 elemen, itu peluang satu dalam 2000, sedangkan untuk 100 elemen probabilitasnya adalah 3,7 * 10 -18). Ketika nilai absolut maksimum hasil komparator meningkat, probabilitas untuk setiap perbandingan untuk mengembalikan negatif atau nol menurun ke 0,5, membuat peluang untuk mengakhiri algoritma yang jauh lebih kecil kemungkinannya (kemungkinan 99 koin membalik semua kepala pendaratan , yang pada dasarnya adalah intinya, adalah 1 dalam 1,2 * 10 30 )
EDIT A LATER TIME LATER: Ada beberapa "macam" yang dirancang khusus sebagai contoh apa yang tidak boleh dilakukan yang menggabungkan pembanding acak; mungkin yang paling terkenal adalah BogoSort. "Diberikan daftar, jika daftar tidak berurutan, kocok daftar dan periksa lagi". Secara teoritis pada akhirnya akan mencapai permutasi nilai yang tepat, seperti "BubbleSort yang tidak dioptimalkan" di atas, tetapi case rata-rata adalah faktorial-waktu (N! / 2), dan karena masalah ulang tahun (setelah permutasi yang cukup Anda menjadi lebih mungkin untuk menghadapi permutasi duplikat daripada yang unik) ada kemungkinan bukan nol dari algoritma tidak pernah menyelesaikan secara resmi algoritma tidak terikat waktu.