Quicksort Bölümleme: Hoare vs. Lomuto


82

Cormen'de belirtilen iki quicksort bölümleme yöntemi vardır:

Hoare-Partition(A, p, r)
x = A[p]
i = p - 1
j = r + 1
while true
    repeat
        j = j - 1
    until A[j] <= x
    repeat
        i = i + 1
    until A[i] >= x
    if i < j
        swap( A[i], A[j] )
    else
        return j

ve:

Lomuto-Partition(A, p, r)
x = A[r]
i = p - 1
for j = p to r - 1
    if A[j] <= x
        i = i + 1
        swap( A[i], A[j] )
swap( A[i +1], A[r] )
return i + 1

Pivot seçme yöntemini göz ardı etmek, hangi durumlarda biri diğerine tercih edilir? Örneğin, yüksek oranda yinelenen değerlerin (yani, dizinin 2 / 3'ten daha fazla olduğu durumlarda, dizinin aynı olduğu), Lomuto'nun göreceli olarak düşük performans gösterdiğini biliyorum;

Başka hangi özel durumlar bir bölümleme yöntemini diğerinden daha iyi yapar?


2
Ben düşünemiyorum herhangi Lomuto Hoare'la daha iyi olduğu durum. Görünüşe göre Lomuto ne zaman ekstra takas yapar A[i+1] <= x. Sıralı bir dizide (ve makul şekilde seçilmiş pivotlar verildiğinde) Hoare hemen hemen hiç takas yapmaz ve Lomuto bir ton yapar (j bir kez hepsinden sonra yeterince küçülür A[j] <= x.) Neyi özlüyorum?
Wandering Logic

2
@WanderingLogic Emin değilim, ama Cormen'in Lomuto bölümünü kitabında kullanma kararı pedagojik olabilir gibi görünüyor - oldukça düz bir döngü değişmez gibi görünüyor.
Robert S. Barnes

2
Bu iki algoritmanın aynı şeyi yapmadığını unutmayın. Hoare'in algoritmasının sonunda, eksen son noktasında değil. Her swap(A[p], A[j])ikisi için de aynı davranışı elde etmek için Hoare'nin sonuna bir tane ekleyebilirsiniz .
Aurélien Ooms

Ayrıca Hoare'nin bölümlemesinin i < j2 tekrar döngüsünü de kontrol etmelisiniz .
Aurélien Ooms

@ AurélienOoms Kod doğrudan kitaptan kopyalanır.
Robert S. Barnes

Yanıtlar:


92

Pedagojik Boyut

Sadeliği nedeniyle Lomuto'nun bölümlendirme yöntemini uygulamak daha kolay olabilir. Jon Bentley’nin Programlama İncisinde Sıralamaya Göre Güzel Bir Anakot

“Quicksort tartışmalarının çoğu iki yaklaşmakta olan endekse dayalı bir bölümleme düzeni kullanıyor [...] [yani Hoare's]. Her ne kadar bu planın temel fikri açık olsa da, ayrıntıları her zaman zor buldum - bir zamanlar iki günün daha iyi bir kısmını kısa bir bölümleme döngüsünde bir hatayı gizleyerek geçirdim. Ön taslakların bir okuyucusu, standart iki indeksli yöntemin aslında Lomuto'nunkinden daha basit olduğundan ve işaret etmek için bazı kodlar çizdiğinden; İki hata bulduktan sonra bakmayı bıraktım. ”

Performans boyut

Pratik kullanım için, verimlilik açısından uygulama kolaylığı feda edilebilir. Teorik olarak, performans karşılaştırması için element karşılaştırmalarının ve takasların sayısını belirleyebiliriz. Ek olarak, gerçek çalışma süresi, önbellekleme performansı ve dal yanlışlıkları gibi diğer faktörlerden etkilenecektir.

Aşağıda gösterildiği gibi, algoritmalar , takas sayısı dışında rastgele permütasyonlarda çok benzer davranır . Orada Lomuto'nun üç katı Hoare kadar ihtiyacı var !

Karşılaştırma Sayısı

n1n

Takas Sayısı

Takas sayısı, dizideki öğelere bağlı olarak her iki algoritma için rastgeledir. Eğer rastgele permütasyonlar varsayarsak , yani tüm elementler farklıdır ve elementlerin her permütasyonu eşit derecede muhtemeldir, beklenen takas sayısını analiz edebiliriz .

1,,n

Lomuto'nun Yöntemi

jA[j]x1,,nx1xx1x

{1,,n}1n

1nx=1n(x1)=n212.

n

Hoare Yöntemi

x

ijxij

x

Hyp(n1,nx,x1)nxx1(nx)(x1)/(n1)x

Son olarak, Hoare'nin bölümlenmesi için beklenen toplam takas sayısını elde etmek için tüm pivot değerlerini tekrar değerlendiririz:

1nx=1n(nx)(x1)n1=n613.

(Daha fazla ayrıntılı bilgi yüksek lisans tezimde , sayfa 29'da bulunabilir.)

Hafıza Erişim Deseni

Her iki algoritma da diziyi içine sırayla tarayan iki işaretçi kullanır . Bu nedenle her ikisi de neredeyse optimal önbellekleme davranırlar.

Eşit Elementler ve Zaten Sıralanan Listeler

Wandering Logic tarafından daha önce belirtildiği gibi, algoritmaların performansı rastgele permütasyonlar olmayan listeler için daha büyük farklılıklar gösterir.

n/2

0ijO(nlogn)

0A[j] <= xi=nΘ(n2)

Sonuç

Lomuto'nun yönteminin uygulanması basit ve kolaydır, ancak bir kütüphane sıralama yöntemini uygulamak için kullanılmamalıdır.


16
Vay, bu ayrıntılı bir cevap. Güzel bitti!
Raphael

Raphael ile aynı fikirdeyim, gerçekten güzel cevap!
Robert S. Barnes

1
Eşsiz öğelerin toplam öğelere oranı arttıkça, Lomuto'nun yaptığı karşılaştırma sayısının Hoare'den önemli ölçüde daha hızlı arttığını açıklığa kavuştururum. Bu, Lomuto'nun tarafında zayıf bölümler ve Hoare'nin bölümünde iyi ortalama bölümlenmelerden kaynaklanıyor olabilir.
Robert S. Barnes,

İki yöntemin harika açıklaması! Teşekkür ederim!
v kouk

Ortalama bir olaya değip değmeyeceğinden emin olmasam da, pivot'a eşit olan tüm unsurları çıkarabilen ve bunları özyinelemeden çıkartabilecek bir Lomuto metodu kolaylıkla oluşturabilirsiniz.
Jakub Narębski

5

Mükemmel Sebastian cevabına bazı yorumlar eklendi.

Genel olarak bölüm yeniden düzenleme algoritması hakkında konuşacağım ve Quicksort için özel kullanımı hakkında değil .

istikrar

Lomuto'nun algoritması yarı yarıya açıktır : yüklemeyi tatmin etmeyen öğelerin göreceli sırası korunur. Hoare'in algoritması kararsız.

Öğe Erişim Örüntüsü

Lomuto'nun algoritması, tek bir bağlantılı liste veya yalnızca ileriye dönük veri yapılarıyla kullanılabilir. Hoare'in algoritması iki yönlülük gerektirir .

Karşılaştırma Sayısı

n1n

Ancak bunu yapmak için 2 özellik feda etmeliyiz:

  1. Bölümlenecek dizi boş olmamalıdır.
  2. Algoritma, bölümleme noktasını döndüremiyor.

n

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.