Neden quicksort pratikte diğer sıralama algoritmalarından daha iyidir?


31

Bu, Janoma tarafından cs.SE’de bir sorunun cevabı . Tam kredi veya ona veya cs.SE'ye tahrif.

Standart algoritmalar kursunda, hızlı bağlantı noktasının ortalama olarak O (n log n) ve en kötü durumda O (n²) olduğu öğrenilir. Aynı zamanda, diğer sıralama algoritmaları (gibi en kötü durumda (n log) Ey olan incelenir MergeSort ve HizliSiralama (gibi iyi durumda ve hatta doğrusal zaman) BubbleSort ) ancak belleğin bazı ek ihtiyaçları olan.

Bazı çalışma sürelerinde hızlıca bir bakıştan sonra , quicksort'un diğerleri kadar verimli olmaması gerektiğini söylemek doğaldır .

Ayrıca, öğrencilerin temel programlama derslerinde genel olarak derslerin özyinelemenin gerçekten iyi olmadığını, çünkü çok fazla bellek kullanabileceğini, vb. Öğrendiklerini göz önünde bulundurun. gerçekten iyi çünkü özyinelemeli bir algoritma.

Öyleyse neden quicksort pratikte diğer sıralama algoritmalarından daha iyi performans gösteriyor? Gerçek dünya verilerinin yapısıyla mı ilgili? Bilgisayarlarda belleğin çalışma şekli ile mi ilgili olmalı? Bazı hatıraların diğerlerinden çok daha hızlı olduğunu biliyorum, ancak bu karşı-sezgisel performansın gerçek nedeni olup olmadığını bilmiyorum (teorik tahminlerle karşılaştırıldığında).


3
Quicksort itibarı, önbellek bulunmadığı bir zamandan başlar.
AProgrammer

9
"neden quicksort pratikte diğer sıralama algoritmalarından daha iyi performans gösteriyor?" Bunun doğru olduğuna emin misin? Bize bu ifade ile atıfta bulunduğunuz gerçek uygulamayı gösterin ve topluluk size bu özel uygulamanın neden böyle davrandığını söyleyecektir. Geriye kalan her şey var olmayan programlar hakkında çılgınca tahminde bulunacak.
Doktor Brown

1
@DocBrown: Pek çok Quicksort (veya bunun türevleri) uygulamaları pek çok kütüphanede seçilmiştir, çünkü tartışmasız en iyi performansı sergilerler (umarım öyledir). Dolayısıyla , Quicksort'u uygulamadan bağımsız olarak hızlı yapan algoritma hakkında bir şeyler olabilir .
Raphael,

1
Birisi bunu eksiksiz olması için söylemeli, bu yüzden şunu söyleyeceğim: Quicksort (genellikle) kararlı değil. Bu nedenle kullanmak istemeyebilirsiniz. Ayrıca, bu nedenle, varsayılan sıralama, istediğiniz ne olsa bile, bir Hızlı Bağlantı olmayabilir.
RalphChapin

1
@Raphael: Genellikle hızlı sıralama denilen aslında intro sıralama (C ++ standart kütüphanesinde kullanılan afaik), saf hızlı sıralama gibi bazı varyasyonlardır.
Giorgio

Yanıtlar:


21

Quicksort'un pratikteki diğer sıralama algoritmalarından daha iyi olduğu konusunda hemfikir değilim.

Çoğu amaç için, Timsort - sıraladığınız verilerin genellikle neredeyse sıralı veya ters sıralı olarak başlaması gerçeğini kullanan birleştirme / ekleme sıralama arasındaki melez.

En basit hızlı bağlantı noktası (rastgele pivot yok), potansiyel olarak yaygın olan bu olayı O (N ^ 2) (rastgele pivotlarla O'ya (N lg N)) düşürürken TimSort bu vakaları O (N) 'de ele alabilir.

C # 'daki bu ölçütlere göre yerleşik quicksort'u TimSort ile karşılaştırarak, Timsort en çok sıralanan vakalarda önemli ölçüde daha hızlı ve rasgele veri durumunda biraz daha hızlı ve karşılaştırma işlevi özellikle yavaşsa TimSort daha iyi hale geliyor. Bu ölçütleri tekrarlamadım ve eğer quicksort bir miktar rastgele veri kombinasyonu için TimSort'u hafifçe vurduysa ya da C # 'nin yerleşik sıralamasında (quicksort'a dayanarak) ilginç olan bir şey varsa onu şaşırtmazdım. Bununla birlikte, TimSort, veriler kısmen sıralandığında belirgin avantajlara sahiptir ve veriler kısmen sıralanmadığında, hız açısından kabaca eşittir.

TimSort ayrıca quicksort'tan farklı olarak, sabit bir sıralama olma avantajına da sahiptir. TimSort'un tek dezavantajı, normal (hızlı) uygulamada O (N) ve O (lg N) belleği kullanır.


18

Çabuk sıralama daha hızlı olduğu için kabul edilir, çünkü katsayı diğer bilinen algoritmalardan daha küçüktür. Bunun için bir sebep veya kanıt yoktur, sadece daha küçük bir katsayılı algoritma bulunamamıştır. Diğer algoritmaların da O ( n log n ) zamanı olduğu doğrudur , ancak gerçek dünyada katsayı da önemlidir.

Küçük veri ekleme sıralamalarının (O ( n 2 ) olduğu düşünülen ) matematiksel fonksiyonların doğası nedeniyle daha hızlı olduğuna dikkat edin. Bu, makineden makineye değişen spesifik katsayılara bağlıdır. (Sonunda, sadece montaj gerçekten çalışıyor.) Bu yüzden bazen hızlı sıralama ve yerleştirme sıralama melezinin pratikte en hızlı olduğunu düşünüyorum.


7
+ Doğru. Öğretmenlerin, sabit faktörlerin büyüklük derecelerine göre değişebileceği gerçeğinin daha farkında (ve ben bir öğretmendim) olması gerekir. Bu yüzden performans ayarlama yeteneği büyük O'dan bağımsız olarak gerçekten önemlidir. Sorun şu ki, gprof öğretmeye devam ediyorlar , çünkü müfredatta bu kurşun noktasını geçmek zorunda kalıyorlar, ki bu 180 derecelik yanlış bir yaklaşım.
Mike Dunlavey

2
“Bunun için bir sebep veya karar yok”: elbette. Yeterince derin kazarsanız, bir sebep bulacaksınız.
Gilles 'SO- kötülük olmayı'

2
@B Seven: çok basitleştirmek için… bir O (n log n) sıralama algoritması için, n maddelerini sıralamak için (n log n) sıralama döngüsünün yinelemeleri vardır. Katsayı, her bir döngü döngüsünün ne kadar sürdüğüdür. N gerçekten büyük olduğunda (en az binlerce), katsayı çok büyük olsa bile katsayı O () kadar önemli değildir. Fakat n küçük olduğunda, katsayı önemlidir - ve sadece 10 maddeyi sıralarsanız en önemli şey olabilir.
Matt Gallagher

4
@MikeDunlavey - iyi bir örnek, fotoğraflarınızı sıralarken O (n ln n) ama daha hızlı olan piramitleri inşa etmenin O (n) olması!
Martin Beckett

2
Yığın ve mergesort gibi garantili O (n log n) algoritmaları vardır, bu nedenle asimptotik en kötü durum terimlerinde Quicksort, en iyisi kadar hızlı değildir. Ancak gerçek dünya performansında bazı hızlı port varyantları son derece iyi çalışıyor. Ancak "katsayı daha küçük" demek, "daha hızlı çünkü daha hızlıdır" demek gibidir. Sabit faktörler neden bu kadar küçük? Temel bir neden, quicksort'un bölge açısından çok iyi olmasıdır - önbellekleri çok iyi kullanır. Mergesort'un da iyi bir yeri var, ancak yerinde yapılması çok zor.
Steve314

16

Quicksort, diğer tüm sıralama algoritmalarından daha iyi performans göstermiyor. Örneğin, aşağıdan yukarıya yığın sıralama ( Wegener 2002 ), makul miktarda veri için hızlı destek performansından daha iyi performans gösterir ve aynı zamanda bir yerinde algoritmadır. Ayrıca uygulanması kolaydır (en azından bazı optimize edilmiş hızlı platform çeşitlerinden daha zor değildir).

O kadar iyi tanınmıyor ve pek çok ders kitabında bulamıyorsunuz; bu neden bunun hızlı bağlantı noktası kadar popüler olmadığını açıklayabilir.


+1: Bazı testler yaptım ve birleştirme sıralama kesinlikle büyük diziler için hızlı sıralamadan daha iyiydi (> 100000 öğe). Öbek sıralama birleştirme düzeninden biraz daha kötüydü (ancak birleştirme düzeninin daha fazla belleğe ihtiyacı var). İnsanların hızlı sıralama dedikleri şeyin intro sıralama olarak adlandırılan bir varyasyon olduğunu düşünüyorum: özyineleme derinliği belirli bir sınırın ötesine geçtiğinde yığın sıralamasına geri dönen hızlı sıralama.
Giorgio,

@Giorgio: quicksort, onu iyileştirmek için bazı şekillerde değiştirilebilir, örneğin burada görün: algs4.cs.princeton.edu/23quicksort Bu iyileştirmeleri denediniz mi?
Doc Brown

İlginç, daha fazla okumak için bir kitap \ sitesine referans verebilir misiniz? (tercihen bir kitap)
Ramzi Kahil

@Martin: Bottom-Up heapsort'u mı kastediyorsunuz? Şey, yukarıda bir referans verdim. Özgür bir kaynak istiyorsanız, alman wikipedia'nın bir makalesi var ( de.wikipedia.org/wiki/BottomUp-Heapsort ). Almanca konuşmasanız bile, sanırım C99 örneğini hala okuyabilirsiniz.
Doktor Brown

7

Sadece en kötü duruma ve sadece zaman karmaşıklığına odaklanmamalısınız. En kötü ihtimalle ortalamadan daha fazlası ve zaman ve mekanla ilgili.

Hızlı sıralama:

  • Bir sahip ortalama (θ'nın zaman karmaşıklığı n log n );
  • space uzay karmaşıklığı ile uygulanabilir (log n );

Ayrıca, büyük O notasyonunun sabitleri hesaba katmadığını, ancak uygulamada eğer algoritmanın birkaç kat daha hızlı olması fark yaratır. Θ ( n log n ) içermesidir, bu algoritma yürüttüğü K  , n  log ( n ), burada K sabittir. Quicksort, en düşük K değerine sahip karşılaştırma-sıralama algoritmasıdır .


1
@Gilles: K değeri düşük, çünkü basit bir algoritma.
vartec

5
O NE LAN? Bu hiç mantıklı değil. Bir algoritmanın basitliği ile çalışma hızı arasında bir ilişki yoktur. Seçim sıralama hızlı bağlantı noktasından daha basittir, bu daha hızlı yapmaz.
Gilles 'SO- kötülük olmayı'

1
@Gilles: seçim sıralama her durumda (en kötü, ortalama ve en iyi) O (n ^ 2) 'dir. Yani ne kadar basit olduğu önemli değil. Quicksort ortalama durum için O (n log n) 'dir ve O (n log n) ile tüm algoritmalar arasında en basit olanıdır.
vartec

1
@Gilles: Diğer şeyler eşit olmak, basitlik performansa yardımcı olur. Her birinin kendi iç döngülerindeki (K n log n) yinelemelerini alan iki algoritmayı karşılaştırdığınızı varsayalım: döngü başına daha az şey yapması gereken algoritmanın performans avantajı vardır.
fırtınalı

1
@formasyon fırtınası: İfadenizin bir totoloji olduğu şeklinde ifade edilir, ancak "basitlik" ile ilgili değildir. Örneğin, daha az çalışma süresiyle sonuçlanan (hem teoride hem pratikte) Quicksort'un daha karmaşık varyasyonları (vaka farklılıkları!) Vardır.
Raphael

5

Quicksort, genellikle hızlı ve makul derecede hızlı ve uygulanması kolay olduğu için iyi bir seçimdir.

Büyük miktarlarda veriyi çok hızlı bir şekilde sıralama konusunda ciddiyseniz, MergeSort'taki bazı değişikliklerde muhtemelen daha iyi olursunuz. Bu, harici depolamadan yararlanmak için yapılabilir, birden fazla iş parçacığından ve hatta işlemden faydalanabilir, ancak kodlama için önemsiz değildir.


1

Algoritmaların gerçek performansı, platforma, diline, derleyiciye, programcının uygulama detayına dikkat etmesi, özel optimizasyon çabası, vb. Bu nedenle, quicksort'un "sabit faktör avantajı" çok iyi tanımlanmamıştır - şu anda mevcut araçlara dayanan öznel bir yargılama ve karşılaştırmalı performans çalışmasını gerçekte yapan kişi tarafından "eşdeğer uygulama çabası" hakkında kaba bir tahmindir. .

Bununla birlikte, quicksort'un (randomize giriş için) iyi performans gösterdiğine inanıyorum, çünkü basit ve özyinelemeli yapısı nispeten önbellek dostu. Öte yandan, en kötü durumunun tetiklenmesi kolay olduğu için, bir hızlı bağlantı noktasının herhangi bir pratik kullanımının, ders kitabı açıklamasından gösterdiğinden daha karmaşık olması gerekecektir: bu nedenle, introsort gibi değiştirilmiş sürümler gerekir.

Zaman içinde, baskın platform değiştikçe, farklı algoritmalar (tanımsız) göreceli avantajlarını kazanabilir veya kaybedebilir. Göreceli performans konvansiyonel bilgeliği bu değişimin gerisinde kalabilir, bu nedenle, hangi algoritmanın uygulamanız için en iyi olduğundan emin değilseniz ikisini de uygulamanız ve test etmeniz gerekir.


Sanırım "daha küçük sabit" diğerleri bunun resmi analizde olduğu, yani karşılaştırmalar veya takas sayıları ile ilgili olduğu ile ilgili. Bu çok iyi tanımlanmıştır ancak bunun çalışma zamanına nasıl dönüştüğü belirsizdir. Bir meslektaşım şu anda aslında biraz araştırma yapıyor.
Raphael,

Benim izlenimim bunun genelleştirilmiş bir performans ile ilgili olduğuydu, ama ben de buna güvenmezdim. Yine de haklısın: eğer karşılaştırmanız özellikle
pahalıysa

1
Belirtdiğiniz nedenlerden dolayı, genel performanstan (zaman dilimi) bahsetmek, genel durum için çok fazla ayrıntı faktörü olduğu için anlam ifade etmemektedir. “Landau notasyonu (Big-Oh) anlamında, bu sayıları saymak size kaba asimptotikler veriyor. Sabitleri ve / veya çalışma sürelerini göz önünde bulundurduğunuzda, bu strateji çok daha az ilginçtir.
Raphael,

QuickSort'un iyi bir uygulaması, pivot değerlerinin ihtiyaç duyulduğu sürece CPU kaydında kalması için derlenir. Bu, genellikle karşılaştırılabilir Big-O zamanları ile teorik olarak daha hızlı bir sıralama elde etmek için yeterlidir.
Dan Lyons

Farklı sıralama algoritmaları, karşılaştırma sayısı ve yaptıkları değişim sayısı bakımından farklı özelliklere sahiptir. Ve @DanLyons, kütüphanedeki tipik bir dizilimin kullanıcı tarafından sağlanan işlevlerle karşılaştırmalarını yaptığını ve pek çok işlev çağrısı arasında kayıtları tutmanın oldukça zor olduğunu not eder.
Sivri
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.