Apa itu algoritma pengurutan tercepat untuk array bilangan bulat?

55

Saya telah menemukan banyak algoritma penyortiran selama studi sekolah menengah saya. Namun, saya tidak pernah tahu mana yang tercepat (untuk array integer acak). Jadi pertanyaan saya adalah:

  • Manakah algoritma penyortiran tercepat yang saat ini dikenal?
  • Secara teoritis, mungkinkah ada yang lebih cepat? Jadi, apa kompleksitas paling sedikit untuk menyortir?
gen
sumber
7
Apa yang Anda maksud dengan "puasa"? Apa yang ingin Anda ukur?
Raphael
2
Apa yang dimaksud dengan "array acak bilangan bulat"? Acak dengan distribusi apa? distribusi seragam? Gaussian? Bergantung pada distribusi, mungkin ada lebih baik daripada diharapkan menjalankan algoritma waktu. O(nlogn)
Bakuriu
@gen Lihatlah jenis Radix. Implementasi yang benar memiliki kompleksitas O (n) untuk Int32 misalnya.
ini
Silahkan lihat pada benchmark semacam
adrianN
1
@gen: Dalam hal asimptotik? Kemudian, mudah: pilih salah satu algoritma Θ ( n log n ) . Perhatikan bahwa ini mungkin tidak ada hubungannya dengan kinerja dunia nyata (rata-rata). Ini mungkin merupakan bacaan yang bermanfaat dalam hal ini. ΘΘ(nlogn)
Raphael

Jawaban:

42

O(n2)O(n2)O(nlogn)O(nlogn)O(n)

Ω(nlogn)

Ω(n!)

Jawaban ini hanya membahas kompleksitas. Waktu berjalan aktual implementasi algoritma akan tergantung pada sejumlah besar faktor yang sulit diperhitungkan dalam satu jawaban.

Patrick87
sumber
OΩ
1
ΘΩ
7
Ω
2
@RealzSlaw: Saya akan memakainya dengan bangga. :]
Raphael
1
@gen Lihat stackoverflow.com/a/3274203 untuk beberapa diskusi. Pada dasarnya, jika catatan individual sangat besar, dan itu tidak disimpan dengan cara akses acak, dan jumlah data sedemikian rupa sehingga harus dilakukan di tempat, maka bubble sort adalah cara yang harus dilakukan. Keadaan ini biasanya jarang terjadi saat ini, tetapi Anda mungkin masih menjumpai mereka.
Patrick87
16

Jawabannya, seperti yang sering terjadi pada pertanyaan semacam itu, adalah "itu tergantung". Itu tergantung pada hal-hal seperti (a) seberapa besar bilangan bulat itu, (b) apakah array input berisi bilangan bulat dalam urutan acak atau dalam urutan hampir diurutkan, (c) apakah Anda memerlukan algoritma pengurutan agar stabil atau tidak, serta faktor-faktor lain, (d) apakah seluruh daftar angka sesuai dengan memori (jenis di-memori vs jenis eksternal), dan (e) mesin tempat Anda menjalankannya.

Dalam praktiknya, algoritma pengurutan dalam pustaka standar bahasa Anda mungkin akan cukup bagus (cukup dekat dengan optimal), jika Anda memerlukan jenis memori. Oleh karena itu, dalam praktiknya, cukup gunakan fungsi apa pun yang disediakan oleh perpustakaan standar, dan ukur waktu berjalan. Hanya jika Anda menemukan bahwa (i) penyortiran adalah sebagian besar dari keseluruhan waktu berjalan, dan (ii) waktu berjalan tidak dapat diterima, jika Anda repot-repot bermain-main dengan algoritma penyortiran. Jika kedua kondisi tersebut berlaku, maka Anda dapat melihat aspek spesifik dari domain tertentu dan bereksperimen dengan algoritma pengurutan cepat lainnya.

Namun secara realistis, dalam praktiknya, algoritma pengurutan jarang menjadi hambatan kinerja utama.

DW
sumber
9

Selanjutnya, jawab pertanyaan kedua Anda

Secara teoritis, mungkinkah ada yang lebih cepat?
Jadi, apa kompleksitas paling sedikit untuk menyortir?

Untuk penyortiran tujuan umum, kompleksitas masalah penyortiran berbasis perbandingan adalah Ω (n log n) . Ada beberapa algoritma yang melakukan pengurutan dalam O (n), tetapi mereka semua bergantung pada membuat asumsi tentang input, dan bukan algoritma pengurutan tujuan umum.

Pada dasarnya, kompleksitas diberikan oleh jumlah perbandingan minimum yang diperlukan untuk mengurutkan array (log n mewakili ketinggian maksimum pohon keputusan biner yang dibangun ketika membandingkan setiap elemen array).

Anda dapat menemukan bukti formal untuk menyortir kompleksitas yang lebih rendah di sini :

rla4
sumber
3
Ω(nlogn)
Tergantung pada apa yang Anda maksud dengan masalah penyortiran . Jenis berbasis perbandingan tujuan umum bukan satu-satunya jenis masalah penyortiran yang dimiliki orang.
Patrick87
1
Itu benar, tentu saja. Saya seharusnya lebih spesifik, terima kasih telah menunjukkannya. Namun, saya agak penasaran tentang pendekatan penyortiran lainnya (bukan berbasis perbandingan) yang Anda maksud; Radix Sort adalah jenis algoritma O (n) yang saya bicarakan - Anda harus 'mengasumsikan' sesuatu tentang input (integer lebar tetap). Dalam hal ini, ini bukan algoritma penyortiran untuk tujuan umum, bukan?
rla4
1
@ WD: Radix sort tidak boleh dianggap sebagai algoritma sortir 'tujuan umum', karena membutuhkan kunci integer panjang tetap; apakah itu tidak berguna sebaliknya. Tapi saya mengerti maksud Anda. :) Saya kira kesalahan saya berfokus pada menyortir aything yang dapat dibandingkan, bukan menyortir bilangan bulat , khususnya. Mereka adalah masalah yang berbeda, dan memiliki serangkaian solusi yang berbeda. Pertanyaannya memang menyebutkan "array acak bilangan bulat", tapi saya akui saya menganggapnya sebagai contoh, bukan pembatasan.
rla4
2
@ DavidRicherby, melihat kembali setelah satu setengah tahun, saya setuju dengan Anda. Terima kasih.
DW
3

O(nloglogn)O(nlogn)

pengguna39994
sumber
2
nlognΩ(nlogn)O(nloglogn)
David Richerby
1

Saya membaca dua jawaban lainnya pada saat menulis ini dan saya tidak berpikir salah satu menjawab pertanyaan Anda dengan tepat. Jawaban lain dianggap ide-ide asing tentang distribusi acak dan kompleksitas ruang yang mungkin di luar ruang lingkup untuk studi sekolah menengah. Jadi inilah yang saya ambil.

An(n1)A(n1)Ω(n)O(n)Ω(n)

Ω(n)O(n)n2n3n51n2

bourbaki4481472
sumber
O(n)nlgnn232O(n)O(nlgn)(untuk quicksort atau mergesort), dalam praktiknya perbandingannya tidak terlalu jelas: konstanta yang tersembunyi dalam notasi O-besar menjadi sangat penting, dan konstanta untuk radix-sort lebih tinggi daripada konstanta untuk quicksort atau mergesort.
DW
lg(n)n
Ω(n)
2
O(wn)www{0,,2w1}lognnw=lognnlogn.
David Richerby
1

O(nloglogn)
O(nloglogU)U
kebodohan
sumber
0

log(n!)

Ω(n)

Yves Daoust
sumber
0

Karena Anda tidak menyebutkan batasan pada perangkat keras dan mengingat Anda mencari "yang tercepat", saya akan mengatakan Anda harus memilih salah satu algoritma pengurutan paralel berdasarkan perangkat keras yang tersedia dan jenis input yang Anda miliki.

Secara teori misalnya quick_sortadalah O(n log n). Dengan pprosesor, idealnya ini harus turun O(n/p log n)jika kita menjalankannya secara paralel.

Mengutip Wikipedia: Kompleksitas waktu ...

Penyortiran paralel optimal adalah O (log n)

Dalam praktiknya, untuk ukuran input masif tidak mungkin tercapai O(log n)karena masalah skalabilitas.

Berikut ini adalah kode pseudo untuk pengurutan Paralel paralel . Implementasi merge()bisa sama seperti dalam penggabungan normal:

// Sort elements lo through hi (exclusive) of array A.
algorithm mergesort(A, lo, hi) is
    if lo+1 < hi then  // Two or more elements.
        mid = ⌊(lo + hi) / 2⌋
        fork mergesort(A, lo, mid)
        mergesort(A, mid, hi)
        join
        merge(A, lo, mid, hi)

Lihat juga:

Kashyap
sumber
O(n2)
@ Evil Ya. Quicksort tidak cocok untuk pemrosesan paralel. Itu sebuah contoh. Yang harus digunakan tercantum dalam tautan yang diberikan.
Kashyap