Bir tamsayı dizisi için en hızlı sıralama algoritması nedir?


55

Lise çalışmalarım sırasında birçok sıralama algoritmasına rastladım. Ancak hangisinin en hızlı olduğunu asla bilemem (rastgele bir tamsayılar dizisi için). Yani benim sorularım:

  • Şu anda bilinen en hızlı sıralama algoritması hangisi?
  • Teorik olarak, daha hızlı olanlar olması mümkün mü? Peki, sıralama için en az karmaşık olan nedir?

7
"Hızlı" derken ne demek istiyorsun? Ne ölçmek istiyorsun?
Raphael

2
"Rasgele tamsayı dizisi" ne demek? Hangi dağılımla rastgele? üniforma dağıtımı? Gauss? Dağılıma bağlı olarak, beklenen çalışma zamanı algoritmalarından değerinden daha iyi olabilir . O(nlogn)
Bakuriu

@gen Radix türüne bir bakın. Doğru uygulama, örneğin Int32 için O (n) karmaşıklığına sahiptir.
bu


1
@gen: asimptotics açısından ? O zaman kolaydır: algoritmalarından herhangi birini seçin . Bunun (ortalama) gerçek dünya performansı ile ilgisi olmayabileceğini unutmayın . Bu , bu konuda okunan değerli olabilir. Θ ( n log n )ΘΘ(nlogn)
Raphael

Yanıtlar:


42

Genel terimlerle, tipik olarak yalnızca özel durumlarda kullanmanız gereken ekleme sıralama, kabarcık sıralama ve seçim sıralama gibi sıralama algoritmaları vardır; İyi durum sabitleri ve özellikleri olan ve genel amaçlı bir sıralama prosedürü olarak kullanılabilen , en kötü durum olan ancak oldukça sık olan Quicksort ; aynı zamanda iyi bir genel amaçlı sıralama algoritması olan birleştirme-tür ve yığın tür gibi algoritmalar; ve listelerinizdeki tam sayıların yapısına bağlı olarak uygun olabilecek tam sayı listeleri için sayı tabanı, kepçe ve sayma türleri gibi veya doğrusal sıralama algoritmaları.0 ( n 2 ) 0 ( n log n ) O ( n log n ) O ( n )O(n2)O(n2)O(nlogn)O(nlogn)O(n)

Listenizdeki öğeler onlar hakkında bildiğiniz kadarıyla ise, aralarındaki toplam sıra ilişkisi ise, optimal sıralama algoritmaları karmaşıklığı olacaktır . Bu oldukça havalı bir sonuçtur ve bunun için çevrimiçi olarak kolayca bilgileri bulmanız gerekir. Doğrusal sıralama algoritmaları, yalnızca öğeler arasındaki toplam sıra ilişkisinden ziyade, sıralanacak öğelerin yapısı hakkında daha fazla bilgi kullanır.Ω(nlogn)

Daha genel olarak, bir sıralama algoritmasının iyeliği, sıralayacağınız listelerin türüyle ilgili yapabileceğiniz varsayımlara (algoritmanın çalışacağı makine modeline ek olarak zayıf bir sıralama bile yapabilir) en iyi seçimi algoritmalar; depolama için bandı olan makinelerde kabarcık sıralamasını düşünün). Varsayımlarınız ne kadar güçlüyse, algoritmanız o kadar fazla köşeyi kesebilir. Bir listenin "sıralanmasını" ne kadar etkili bir şekilde belirleyebileceğinize dair çok zayıf varsayımlar altında, en iyi en kötü durum karmaşıklığı bile Olabilir .Ω(n!)

Bu cevap sadece karmaşıklıklarla ilgilidir. Algoritmaların gerçek uygulama süreleri, tek bir cevapta hesaba katılması zor olan çok sayıda faktöre bağlı olacaktır.


Bunlardan bazıları tahmin edilmelidir ? ΩOΩ
Raphael

1
@Raphael Meh. Bence çoğu zaten . Sanırım alt sınır muhtemelen daha iyi bir hale getirildi . En mantıklı olan birkaç tanesini değiştireceğim. ΩΘΩ
Patrick87

7
@Raphael polis şapkası aldı : PΩ
Realz Slaw

2
@RealzSlaw: Gururla giyerdim. :]
Raphael

1
@gen Bazı tartışmalar için stackoverflow.com/a/3274203 adresine bakın . Temel olarak, eğer bireysel kayıtlar çok büyükse ve rastgele erişimli bir şekilde depolanmadıysa ve veri miktarı yerinde yapılması gereken şekilde ise, o zaman kabarcık sıralaması gitme yoludur. Bu koşullar günümüzde genellikle nadirdir, ancak yine de onlarla karşılaşabilirsiniz.
Patrick87

16

Cevap, çoğu zaman olduğu gibi, bu tür sorular için geçerli olduğu gibi, "bağlıdır". (A) tamsayıların ne kadar büyük olduğu gibi şeylere bağlıdır, (b) giriş dizisinin tamsayıları rasgele bir sırada mı yoksa neredeyse sıralı bir sırada mı içerdiğini, (c) sıralama algoritmasının kararlı olması gerekip gerekmediği, diğer faktörlerin yanı sıra, (d) tüm sayılar listesinin belleğe uyup uymadığı (hafıza içi sıralama veya harici sıralama) ve (e) çalıştırdığınız makine.

Uygulamada, dilinizin standart kitaplığındaki sıralama algoritması, bellek içi bir sıralamaya ihtiyacınız varsa muhtemelen oldukça iyi (optimal seviyeye oldukça yakın) olacaktır. Bu nedenle pratikte standart kütüphane tarafından sağlanan sıralama işlevini kullanın ve çalışma süresini ölçün. Yalnızca (i) sıralamanın genel çalışma süresinin büyük bir kısmını bulduğunu ve (ii) çalışma süresinin kabul edilemez olduğunu tespit ederseniz, sıralama algoritması ile uğraşmamanız gerekir. Bu iki koşul ise do tutun, o zaman belirli bir etki belirli yönleri bakmak ve diğer hızlı sıralama algoritması ile deneme yapabilirsiniz.

Fakat gerçekçi olarak, pratikte, sıralama algoritması nadiren büyük bir performans darboğazıdır.


9

Dahası, ikinci sorunuza cevap vermek

Teorik olarak daha hızlı olanlar olması mümkün mü?
Peki, sıralama için en az karmaşık olan nedir?

Genel amaçlı sıralama için, karşılaştırma tabanlı sıralama problemi karmaşıklığı Ω (n log n) 'dir . O (n) 'de sıralama yapan bazı algoritmalar vardır, fakat hepsi girdi hakkında varsayımlarda bulunurlar ve genel amaçlı sıralama algoritmaları değildir.

Temel olarak, karmaşıklık, diziyi sıralamak için gereken minimum karşılaştırma sayısıyla verilir (log n, dizinin her öğesini karşılaştırırken oluşturulan bir ikili karar ağacının maksimum yüksekliğini gösterir).

Karmaşıklık alt sınırını sıralamak için resmi kanıtı burada bulabilirsiniz :


3
Ω(nlogn)

Sıralama problemi ile ne demek istediğine bağlı . Genel amaçlı karşılaştırma tabanlı türler, insanların sahip olduğu tek tür sıralama sorunları değildir.
Patrick87

1
Tabii ki bu doğru. Daha belirgin olmalıydım, gösterdiğin için teşekkürler. Ancak, başka hangi sıralama yaklaşımlarına (karşılaştırma tabanlı değil) atıfta bulunduğunuzu biraz merak ediyordum; Radix Sort, tam olarak bahsettiğim O (n) algoritmasının türüdür - girdi hakkında bir şeyler varsaymanız gerekir (sabit genişlikli tamsayılar). Bu anlamda, genel amaçlı bir sıralama algoritması değildir, değil mi?
rla4

1
@DW: Radix sıralama, sabit uzunluklu tamsayı tuşları gerektirdiğinden “genel amaçlı” bir sıralama algoritması olarak görülmemelidir; Aksi takdirde yararlı değil mi. Ama ben senin fikrini anlıyorum. :) Sanırım benim hatam , özellikle tamsayıları sıralamak yerine, karşılaştırılabilecek her şeyi sıralamaya odaklanmaktı . Bunlar farklı problemlerdir ve farklı olası çözümlere sahiptirler. Soru, "rastgele bir tamsayı dizisi" dir, ancak bir kısıtlamadan ziyade örnek aldığımı itiraf ediyorum.
rla4

2
@DavidRicherby, bir buçuk yıl sonra geriye dönüp baktığımda, sana katılıyorum. Teşekkür ederim.
DW

3

O(nloglogn)O(nlogn)


2
nlognΩ(nlogn)O(nloglogn)
David Richerby 19:15 21:

1

Bunu yazarken diğer iki cevabı okudum ve hiçbirinin sorunuzu uygun şekilde cevapladığını sanmadım. Diğer cevaplar, muhtemelen lise çalışmaları kapsamı dışında olan rastgele dağılımlar ve uzay karmaşıklığı hakkında dış fikirleri düşündü. Yani burada benim almam.

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

Ω(n)O(n)n2n3n51n2


O(n)nlgnn232O(n)O(nlgn)(quicksort veya mergesort için) pratikte karşılaştırma o kadar açık değildir: big-O notasyonunda saklanan sabitler çok önemlidir ve radix-sıralama sabiti, quicksort veya birleştirme sabitinden daha yüksektir.
DW

lg(n)n

Ω(n)

2
O(wn)www{0,,2w1}lognnw=lognnlogn.
David Richerby

1

O(nloglogn)
O(nloglogU)U


0

Donanımda herhangi bir kısıtlamadan bahsetmediğiniz ve "en hızlı" terimi aradığınız göz önüne alındığında, mevcut donanıma ve sahip olduğunuz girdi türüne göre paralel sıralama algoritmalarından birini seçmeniz gerektiğini söyleyebilirim.

Teoride örn quick_sortolduğunu O(n log n). İle pişlemciler, ideal olarak bu kadar inmesi gerektiğini O(n/p log n)biz paralel olarak çalıştırmak eğer.

Wikipedia'dan alıntı yapmak için: Zaman karmaşıklığı ...

En uygun paralel sıralama O (log n)

Uygulamada, büyük girdi boyutları O(log n)için ölçeklenebilirlik sorunları nedeniyle elde edilmesi imkansız olacaktır .

Paralel birleştirme sıralama için sözde kod . Uygulaması merge()normal birleştirme sıralamasında olduğu gibi aynı olabilir:

// 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)

Ayrıca bakınız:


O(n2)

@Evil Evet. Quicksort paralel işleme için uygun değil. Bu bir örnek. Kullanılması gerekenler verilen bağlantılarda listelenmiştir.
Kashyap
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.