COMPUTER ENGINEER

← BlogDATA STRUCTURES / ALGORITHMSPython örnek paketi ↓

Arama ve sıralama · 14 / 53

Merge sort ve dış sıralama

Anla → iz sür → uygula → gerekçelendir

3 dk okuma · uygulama için ayrıca zaman ayır

Merge sort veriyi ikiye böler, iki sıralı yarıyı iki pointer ile birleştirir. Birleştirme invariant'ı: sonuçta seçilmiş öğeler sıralıdır, kalan iki listenin başındaki en küçük öğe sonraki doğru seçimdir. Eşit anahtarda sol öğeyi önce alırsan stabiliteyi korursun.

Dengeli bölme sıralı/ters/tekrarlı girdilerde aynı Θ(n log n) zaman sınırını verir. Standart dizi uygulaması geçici tampon kullanır. Python slicing yarıları kopyalar; teorik indeks tabanlı uygulamayla allocation davranışı birebir aynı değildir. Linked list merge sort bağlantıları değiştirebilir fakat recursion alanı yine dikkate alınır.

Veri RAM'e sığmazsa external merge sort kullanılır: belleğe sığan run'ları sıralayıp diske yaz, sonra k-way merge yap. Öncelik kuyruğu her run'ın başını tutar; I/O, disk blokları ve buffer sayısı artık esas maliyet modelidir. Her şeyi RAM'e almak dış sıralama değildir.

Sıralama algoritması seçme atlası

AlgoritmaWorst-case zamanTipik ek alanStable?
InsertionΘ(n²)O(1), in-place modelEvet, strict karşılaştırmayla
MergeΘ(n log n)O(n), standart array mergeEvet, eşitlikte soldan seç
QuickΘ(n²)Stack: worst O(n)Standart swap sürümü hayır
HeapΘ(n log n)O(1), iteratif in-placeHayır
CountingΘ(n+k)O(n+k), stable outputUygun uygulamayla evet
RadixΘ(d(n+k))Digit yöntemine bağlıHer pass stable olursa

Quick sort'un expected Θ(n log n) süresi worst-case Θ(n²)'yi silmez. Merge sort bağlı listede node relinking ile farklı ek alan takası sunabilir. Python örneğinde slice allocation vardır; teorik in-place iddiası bu koda otomatik aktarılmaz.

Merge invariantı: sonuç prefix'i sıralıdır ve tüketilmiş iki prefix'in bütün elemanlarını tam bir kez içerir. Bir sonraki küçük head'i seçmek bu invariantı korur. Eşit key'de soldan seçmek önceki sıra bilgisini korur. Sonunda kalan tek taraf zaten sıralı olduğundan eklenir.

Temel: [2,5,8] ile [1,5,7] merge'ünü trace et. Orta: (key, originalIndex) çiftleriyle stability testini yaz. İleri: RAM'e sığmayan 100 GB veri için run üretimi, fan-in, buffer boyutu ve disk pass sayısını tahmin et; RAM Big-O yerine I/O modelini kullan.

Adım adım iz sürme

[5,1,4,2] → [1,5] ve[2,4]. Başları seç:1,2,4; kalan5'+'’i ekle. Eşitlikte sol seçimi kayıt sırasını korur.

Maliyet ve varsayımlar

T(n)=2T(n/2)+Θ(n)=Θ(n log n). Bu slicing uygulaması O(n) tepe yardımcı alan, O(log n) stack kullanır.

Çalıştırılabilir örnek

Python 3 ile çalıştır. Assert küçük bir örneği denetler; genel doğruluk ispatı değildir. Bazı ileri örnekler özellikle küçük model veya referans oracle'dır; tam üretim uygulaması değildir.

Python 3
def merge_sort(a):
    if len(a) < 2: return list(a)
    m = len(a)//2
    left, right = merge_sort(a[:m]), merge_sort(a[m:])
    out, i, j = [], 0, 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]: out.append(left[i]); i += 1
        else: out.append(right[j]); j += 1
    return out + left[i:] + right[j:]
assert merge_sort([5,1,4,2]) == [1,2,4,5]

KAVRADIĞINI KONTROL ET

Sıra sende

100 GB dosya, 1 GB RAM: hangi tasarım?

Çözümün mantığını göster

Bellek sınırını aşmayan run'+'’lar, disk ara dosyaları, buffered k-way merge, kaynağı kapatma ve disk alanı/hata yönetimi. Bütün dosyayı list() ile okumamak gerekir.

Bir adım ileri

  1. Örneği değiştirmeden önce girdi sözleşmesini ve invariantı yaz.
  2. Uygun olan boş, sınır, tekrar ve adversarial girdileri ekle. Basit bir oracle ile karşılaştır.
  3. Belirtilen modelde maliyeti çıkar; farklı girdi büyüklüklerini ölç ve farkları gerekçelendir.

Temel kaynaklar ve ders notları

Bu eğitimde özgün anlatım kullanıldı; aşağıdaki kaynaklar ispatlar ve ileri okumalar sunar. Bağlantılar daha geniş ders modülünü kapsayabilir.

Princeton · Algorithms, Sedgewick & Wayne ↗Pat Morin · Open Data Structures ↗
İlerlemeden önce alıştırmayı çöz.