T: tema · Z: kodu büyüt · S: konuşmacı notları · F: tam ekran · Esc: genel bakış · ⌂ ders haritası
OYUNLARDA YAPAY ZEKÂ · SIRALAMA
Quicksort
Bir pivot seç, etrafında böl — pratikte en hızlı sıralama ve onun riskleri
PRESS ▶ TO START

Bu derste oyunun haritası 🗺️

  1. Bölümleme — pivotun solu küçük, sağı büyük partitioning
  2. Quicksort — böl, sonra iki tarafı sırala
  3. Analiz — ortalama 1,39 N lg N ama en kötü N²! Karıştırmanın önemi
  4. İyileştirmeler — küçük parçalar, üçün ortancası
  5. Tekrar eden anahtarlar — üç yollu bölümleme (Hollanda bayrağı)
  6. Seçim — sıralamadan medyan ve en yakın k düşman quickselect
  7. Oyunda bölümleme — canlılar başa, ölüler sona
  8. Sistem sıralamaları — C#, Python, JS içeride ne kullanıyor?
🎮 Bu dersin sonunda…

…FPS testlerindeki “%1 low” değerinin nasıl hesaplandığını bilecek ve hazır Sort()’un neden bazen kararsız olduğunu açıklayabileceksiniz.

🤔 ISINMA: BOY SIRASI

30 kişilik bir sınıfı boy sırasına dizeceksiniz. Herkesle herkesi karşılaştırmadan.

Bir öğrenciyi seçin: Ali. “Ali’den kısalar sola, uzunlar sağa!” Bir anda Ali tam yerine oturdu.

Şimdi soldaki grup için de birini seçin, aynısını yapın; sağdaki grup için de…

Ali’nin adı: pivot. Bu fikrin adı: quicksort.

Mini sözlük

pivotpivot (mihenk)Etrafında bölümleme yaptığımız eleman
partitionbölümlemePivotun solu ≤, sağı ≥ olacak şekilde yeniden dizmek
in-placeyerindeEk dizi kullanmadan (sadece takaslarla)
randomizedrastgeleleştirilmişKötü girdilere karşı önce karıştırmak
3-way partitioningüç yollu bölümleme< pivot · = pivot · > pivot
selection / quickselectseçimk. en küçük elemanı (ör. medyan) bulmak
percentileyüzdelikVerilerin %p’sinin altında kaldığı değer
introsortintrosortQuicksort + kötü giderse heapsort’a geçiş (C#, C++)
LEVEL 0
Bölümleme
partitioning — pivotun solu küçük, sağı büyük
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

Bölümleme: i soldan, j sağdan

  1. Pivot: v = a[lo]
  2. i soldan ilerler: a[i] < v olduğu sürece
  3. j sağdan geriler: a[j] > v olduğu sürece
  4. İkisi de durduysa: a[i] ile a[j]’yi takasla, devam
  5. i ve j kesişince: pivotu a[j] ile takasla → pivot son yerinde!
Bölümlemeden sonra
  • a[j] son yerinde
  • solundakilerin hiçbiri a[j]’den büyük değil
  • sağındakilerin hiçbiri a[j]’den küçük değil

Bölümleme — animasyon

pivotkarşılaştırılantakaslanan

İz tablosu: bölümleme partitioning trace

kırmızı = pivot · mavi = az önce takaslanan a[i] ve a[j] · gri = dokunulmayan

Bölümleme — kod

🎒 while True: / for (;;): “sonsuza kadar dön” — döngüden break ile çıkılır. Koşul ortada kontrol edildiği için bu kalıp kullanılır.

🔗 Başka gözle: etkileşimli anlatımlar ve yazılar

Aynı konuyu başka bir anlatımla, kendi elinizle oynayarak görmek çok işe yarar. Kartlar yeni sekmede açılır; çoğu İngilizce ama görsel ve etkileşimli.

Quiz 1 · bölümleme
[5, 9, 1, 7, 3] dizisi pivot 5 ile bölümlenirse pivot hangi indekse yerleşir?
5’ten küçük iki eleman var (1 ve 3) → sıralı dizide 5’in yeri 2 numaralı indeks. Bölümleme, pivotu tam sıralı dizideki yerine koyar (geri kalanlar henüz sırasız olsa bile). Örneğin sonuç: [1, 3, 5, 7, 9] ya da [3, 1, 5, 9, 7].
LEVEL 1
Quicksort
böl, sonra iki tarafı (özyinelemeyle) sırala
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

Quicksort — kod

  1. Diziyi karıştır (neden? birazdan!)
  2. Bölümle: pivot son yerine otursun
  3. Solu ve sağı özyinelemeyle sırala
Mergesort ile karşılaştırmaMergesort: önce sırala, sonra işi yap (birleştir). Quicksort: önce işi yap (bölümle), sonra sırala. Birleştirme adımı yok, ek dizi yok!

İz tablosu: quicksort

kırmızı = bu adımda son yerine oturan pivot · siyah = bölümlenen parça a[lo…hi] · gri = bu adımın dışı

Quicksort — animasyon

pivotkarşılaştırılantakaslananşu an bölümlenen parça

📜 Tony Hoare, Moskova, 1960

Genç İngiliz bilgisayar bilimci Tony Hoare, Moskova Devlet Üniversitesi’nde Rusça–İngilizce makine çevirisi üzerinde çalışıyordu. Çevrilecek cümledeki kelimeleri, manyetik şeritteki sözlükte aramadan önce sıralaması gerekiyordu.

Insertion sort çok yavaştı. Hoare quicksort’u buldu — ama dönemin dillerinde özyineleme yoktu, programı yazamadı! İngiltere’ye dönüp özyinelemeli ALGOL 60’ı öğrenince yazabildi.

💸 “Milyar dolarlık hatam”Hoare 1965’te bir programlama diline null referansı ekledi, çünkü “gerçekleştirmesi çok kolaydı”. 2009’da bunun “milyar dolarlık hatası” olduğunu söyledi: NullReferenceException hatalarının (bağlı listeler dersi!) atası.
LEVEL 2
Analiz
en iyi N lg N · ortalama 1,39 N lg N · en kötü N²/2
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

Pivot ne kadar iyi bölüyor?

😀 En iyi durumPivot her seferinde tam ortaya düşer → mergesort gibi ikiye bölünür → ~N lg N karşılaştırma.
😱 En kötü durumPivot her seferinde en küçük eleman (ör. dizi zaten sıralı ve karıştırmadık!) → bir taraf boş, diğeri N−1 → ~N²/2 karşılaştırma. Selection sort kadar yavaş!

📐 Ortalama durum ve karıştırmanın önemi

ÖnermeFarklı anahtarlı N elemanı (karıştırdıktan sonra) sıralarken quicksort ortalama ~2 N ln N ≈ 1,39 N lg N karşılaştırma yapar.
  • Mergesort’tan %39 daha çok karşılaştırma… ama pratikte daha hızlı: daha az veri taşıma, ek dizi yok, önbellek dostu.
  • En kötü durum (~N²/2) hâlâ mümkün ama karıştırma sayesinde olasılığı N = 1 milyonda “bilgisayarınıza yıldırım düşmesinden” çok daha düşük.
  • Ağaçlar dersindeki “rastgele BST’nin ortalama derinliği ~2 ln N” ile aynı matematik! (Pivotlar = BST kökleri.)
⚙️ BellekEk dizi yok (yerinde). Sadece özyineleme yığını: ortalama ~lg N derinlik. Ama en kötü durumda derinlik N → yığın taşması! (Çözüm: küçük tarafa özyineleme, büyük tarafa döngü.)

🧪 Canlı ölçüm

🎬 Ara: dansla quicksort

Quick-sort with Hungarian (Küküllőmenti legényes) folk dance
AlgoRythmics (Sapientia Üniversitesi) · 6 dk 54 sn · YouTube’da aç

Pivot şapkayı takan dansçı; soldan ve sağdan gelen dansçılar yer değiştirerek bölümleme yapıyor. Bizim iz tablomuzdaki i ve j işaretçilerinin canlı hâli.

🤔 İzlerkenVideoda pivot hangi eleman seçiliyor? i ve j ne zaman duruyor, ne zaman yer değiştiriyor? Pivot son yerine oturduğunda solundakiler ve sağındakiler hakkında ne biliyoruz?

⚙️ Kötü niyetli girdiler: quicksort’a saldırı

Sabit bir pivot kuralı (ör. “her zaman ilk eleman” ya da “ortadaki”) kullanan bir sıralamaya, onu bilerek yavaşlatan bir girdi hazırlanabilir.

  • 1999’da Doug McIlroy, “Quicksort için öldürücü bir rakip” A Killer Adversary for Quicksort makalesiyle birçok standart kütüphanenin sıralamasını karesel zamana düşürdü.
  • Bir oyun sunucusu, oyuncudan gelen veriyi böyle bir sıralamayla sıralıyorsa: kötü niyetli oyuncu sunucuyu kilitleyebilir (hizmet engelleme, denial of service).
🛡️ Savunmalar
  • Karıştır ya da rastgele pivot seç
  • Introsort (C#, C++): özyineleme çok derinleşirse heapsort’a geç → en kötü N lg N garantisi
  • Ya da garantili bir algoritma: mergesort/Timsort
Quiz 2 · analiz
Karıştırma yapmayan ve pivotu hep a[lo] seçen quicksort’a zaten sıralı 10.000 elemanlı bir dizi veriliyor. Ne olur?
Her bölümlemede pivot en küçük eleman: sol taraf boş, sağ taraf sadece 1 küçülür. Toplam (N−1)+(N−2)+… ≈ N²/2 karşılaştırma ve N derinlikte özyineleme (C#’ta StackOverflowException riski). Oyun verileri çoğu zaman neredeyse sıralıdır → karıştırma şart!
LEVEL 3
İyileştirmeler
küçük parçalar · üçün ortancası
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

İki pratik iyileştirme

1) Küçük parçalara insertion sort~10 elemandan küçük parçalarda özyineleme yükü fazla. Insertion sort’a geç → %20’ye kadar kazanç. (Mergesort’taki ile aynı fikir; .NET bunu ≤ 16 elemanda yapar.)
2) Üçün ortancası median-of-3Pivot olarak ilk, orta ve son elemanın ortancasını seç → pivot ortaya daha yakın düşer, sıralı girdide de iyi çalışır. ~%10 kazanç.

İyileştirmeler — kod

LEVEL 4
Tekrar Eden Anahtarlar
üç yollu bölümleme — Dijkstra’nın Hollanda bayrağı
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

Sadece birkaç farklı değer varsa?

🎮 Envanterdeki 10.000 eşyayı nadirliğe göre sıralıyorsunuz: sadece 4 farklı değer (sıradan, nadir, epik, efsanevi). Ya da sprite’ları 3 çizim katmanına göre…

Eşit anahtarlar zaten birbiriyle sıralı! Onları tekrar tekrar bölümlemek gereksiz.

Üç yollu bölümleme: diziyi üçe ayır:

< v
= v (bitti!)
?
> v

Ortadaki “= v” bölgesi bir daha hiç dokunulmaz. k farklı değer varsa çalışma süresi ~N lg k’ya düşer; az farklı değerde neredeyse doğrusal.

📜 Hollanda bayrağı problemiEdsger Dijkstra (yol bulma derslerinden tanıyacağınız!) bu problemi 1976’da kırmızı, beyaz, mavi toplarla anlattı: “Topları tek geçişte, renklerine göre sıraya diz.” Hollanda bayrağının renkleri. 🇳🇱

Üç yollu quicksort — animasyon (az farklı değer)

Üç yollu bölümleme — kod

LEVEL 5
Seçim
quickselect — sıralamadan medyanı ve en iyi k’yı bulmak
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

k. en küçüğü bul — tamamen sıralamadan

Bölümlemeden sonra pivot j’de. Aradığımız k:

  • j == k → bulduk!
  • j < k → sadece sağ tarafta ara
  • j > k → sadece sol tarafta ara

Quicksort iki tarafa da iner; quickselect tek tarafa → N + N/2 + N/4 + … ≈ 2N: ortalama doğrusal zaman!

🎮 Oyunda
  • Medyan MMR (eşleştirme)
  • En yakın k düşman (sıralama yok!)
  • Skor tablosunda ilk 100 (sadece onları sırala)
  • FPS istatistiği: “%1 low”

Quickselect — kod

C++’ın std::nth_element’i tam olarak budur. Özyineleme yok: tek tarafa indiğimiz için basit bir while yeter.

🎮 “%1 low FPS”: oyuncunun hissettiği takılmalar

Quiz 3 · seçim
1 milyon oyuncunun puanları arasından medyanı bulmak istiyoruz. Hangisi daha hızlı?
Sıralama ~20 milyon karşılaştırma (N lg N), quickselect ortalama birkaç milyon (doğrusal). İkili arama sıralı dizi ister — yani önce sıralamak gerekir. Sadece “k. eleman” lazımsa her şeyi sıralamak boşa iş (sıralama sunumundaki “en yakın düşman” dersi!).
LEVEL 6
Oyunda Bölümleme
tek geçişte: canlılar başa, ölüler sona
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

🎮 Bölümleme tek başına da çok işe yarar

Canlıları başa topla — kod

LEVEL 7
Sistem Sıralamaları
hazır Sort() içeride ne kullanıyor?
  • bölümleme
  • quicksort
  • analiz
  • iyileştirmeler
  • tekrar eden anahtarlar
  • seçim (quickselect)
  • oyunda bölümleme
  • sistem sıralamaları

Kütüphaneler hangi algoritmayı kullanıyor?

dil / fonksiyonalgoritmakararlı?not
C# Array.Sort, List.Sortintrosort (quicksort + heapsort + insertion)✘en kötü N lg N garantili
C# LINQ OrderBykararlı sıralama✔yeni koleksiyon üretir
Python sorted, list.sortTimsort (mergesort + insertion)✔neredeyse sıralıda çok hızlı
JavaScript Array.sortTimsort (V8)✔ES2019’dan beri kararlı
C++ std::sort / stable_sortintrosort / mergesort✘ / ✔Unreal Engine C++
Java (sayılar / nesneler)çift pivotlu quicksort / Timsort✘ / ✔Android

Neden nesneler için kararlı (merge tabanlı), sayılar için quicksort? Sayılarda kararlılığın anlamı yok (eşit sayılar ayırt edilemez) → daha hızlı ve ek bellek istemeyen quicksort seçilir.

Hangi sıralama ne zaman? 📋

algoritmayerindekararlıen kötüortalamaen iyinot
selection✔✘N²/2N²/2N²/2en az takas (N)
insertion✔✔N²/2N²/4Nküçük / neredeyse sıralı
shellsort✔✘N3/2??Nkısa kod
mergesort✘✔N lg NN lg N½N lg Ngaranti, kararlı
quicksort✔✘N²/21,39 N lg NN lg Npratikte en hızlı
3 yollu quick✔✘N²/2< N lg NNtekrar eden anahtarlar
heapsort✔✘2 N lg N2 N lg NN lg N→ öncelik kuyrukları dersi

🏁 Yarış: shellsort, mergesort, quicksort, 3 yollu

🧪 Kod laboratuvarı: partition yaz

İpucu: while (a[++i] < v) if (i === hi) break; · while (v < a[--j]) if (j === lo) break; · if (i >= j) break; · takas. Bonus: daha basit “Lomuto” bölümlemesini araştırıp yazın (tek işaretçi).

🐍 Kod laboratuvarı — Python

Bu kod çoğu zaman çalışır ama bazı testlerde IndexError verir. Neden? (İpucu: pivot dizinin en büyük elemanıysa i nereye kadar gider?) İki sınır kontrolünü ekle.

Derin hikâye: Tony Hoare (1934–2026) ve altı penilik iddia

  • 1959–60: genç Tony Hoare, Moskova Devlet Üniversitesi’nde makine çevirisi üzerinde çalışıyordu; Rusça kelimeleri sözlükte aramak için önce sıralamak gerekiyordu. Quicksort fikri o zaman doğdu.
  • İngiltere’ye dönüp Elliott Brothers’ta çalışmaya başladığında kendisinden Shellsort’u kodlaması istendi. Hoare daha hızlı bir yöntem bildiğini söyledi; patronu buna altı penine iddiaya girdi. Hoare iddiayı kazandı.
  • Algoritmayı 1961’de yayımladı; özyinelemeyi rahatça ifade edebilen ALGOL 60 sayesinde anlatması kolaylaştı. 1980’de Turing Ödülü’nü aldı. 5 Mart 2026’da, 92 yaşında hayatını kaybetti.
  • Sonrası: Doug McIlroy 1999’da “A Killer Adversary for Quicksort” makalesinde, karşılaştırmaları izleyip girdiyi anında uyduran bir “düşman”ın neredeyse her quicksort’u (rastgele pivot seçenleri bile) karesel süreye sokabildiğini gösterdi. Bugünkü kütüphaneler bu yüzden introsort (derinlik sınırı aşılınca heapsort’a geç) ya da pdqsort kullanır.
DersOrtalama durumda en hızlı algoritma, en kötü durumda en tehlikeli olabilir. Saldırgan girdi (sunucuya gönderilen veri, oyuncuların hazırladığı haritalar) varsa en kötü durum gerçek bir risktir: korumayı (rastgelelik, derinlik sınırı) bilerek eklemek gerekir.

Kaynak: Wikipedia: Quicksort · Merton College: Tony Hoare 1934–2026

🧰 Kütüphaneler ve araçlar

adplatformne yapar / sınırlarınasıl eklenir
Array.SortC# / Unityİçgözlemli sıralama: quicksort + derinlik aşılınca heapsort + küçük parçalarda ekleme sıralaması.yerleşik
std::sort · std::nth_elementC++Introsort; nth_element ile ortalama doğrusal sürede k’inci eleman (quickselect).#include <algorithm>
Arrays.sort (ilkel tipler)JavaÇift pivotlu quicksort (Java 7’den beri).yerleşik
slices.Sort · sort_unstableGo · Rustpdqsort ailesi (Go 1.19+); Rust’ın kararsız sıralaması da benzer bir hibrit.yerleşik
heapq.nsmallestPythonSıralamadan en küçük k eleman (yığın ile).standart kütüphane

🧩 Ne zaman kendi quicksort’um?

  • Neredeyse hiçbir zaman: üretimde standart kütüphaneyi kullanın; yıllarca ayarlanmış ve korunmuştur.
  • Bölümleme fikri ise her yerde: “en yakın k düşman” için quickselect (bütün listeyi sıralamadan), “önce aktifler, sonra pasifler” diye yerinde ayırma.
  • Eşit anahtar çoksa (ör. aynı katmandaki 10.000 sprite) 3-yollu bölümleme.
  • Kendiniz yazarsanız: rastgele pivot (ya da üçün ortancası), küçük parçalarda ekleme sıralaması, derinlik sınırı.
Özyineleme derinliğiKötü pivotlarla özyineleme derinliği N’ye ulaşır: büyük dizide yığın taşması. Daha kısa parçaya özyineleme, uzun parçaya döngü uygulamak derinliği log N ile sınırlar.

🤖 Bu konuyu bir YZ kod asistanıyla yazarken

Sık yapılan hatalar — kontrol edin
  • İlk elemanı pivot almak (sıralı girdide O(n²))
  • Her çağrıda new Random() oluşturmak
  • Özyineleme derinliğini sınırlamamak
  • Çok eşit anahtarda 2-yollu bölümleme
İyi bir istek (prompt) örneği

“C# (.NET 8). En yakın k düşmanı bulmak için quickselect yaz: girdi (konumlar dizisi, oyuncu konumu, k), mesafenin karesiyle karşılaştır, tohumlu Random ile pivot seç, en kötü durumda derinlik sınırı aşılınca heap tabanlı seçime geç. NUnit testleri: k = 0, k = n, tekrarlı mesafeler, sıralı girdi; sonuçları tam sıralamayla karşılaştır.”

  • Pivot stratejisini ve derinlik sınırını açıkça isteyin
  • Sıralı, ters sıralı, hep-eşit girdilerle test isteyin
  • Tohumlu rastgele üreteç isteyin
  • Top-k için quickselect ya da yığın sorun

🚀 Proje ve araştırma önerileri

  1. [kolay] Quickselect ile en yakın k — Unity’de 1.000 düşman arasından en yakın 5’ini her kare quickselect ile bulun; tam sıralamayla ölçün.
  2. [orta] Düşman girdi — McIlroy’un fikrini kendi basit quicksort’unuza uygulayın: karşılaştırma sayısının nasıl karesel büyüdüğünü gösterin.
  3. [orta] 3-yollu bölümleme görselleştirmesi — Hollanda bayrağı problemini p5.js’te animasyonla gösterin.
  4. [araştırma] Hibritler — Kendi introsort’unuzu yazıp Array.Sort ile ölçün; eşik değerlerinin etkisini inceleyin.

📄 Akademik okumalar ve kaynaklar

Hoare 1962 · Quicksort (The Computer Journal 5(1))
Algoritmanın tam anlatımı.
McIlroy 1999 · A Killer Adversary for Quicksort (Software: Practice and Experience 29(4))
Her quicksort’u karesele sokan düşman.
Bentley & McIlroy 1993 · Engineering a Sort Function (Software: Practice and Experience 23(11))
C kütüphanesi qsort’unun tasarımı.
Peters 2021 · Pattern-defeating Quicksort (arXiv)
pdqsort.

Neler öğrendik? 🎒

  • Bölümleme: i soldan, j sağdan; pivot son yerine.
  • Quicksort: böl, sonra iki tarafı sırala; yerinde.
  • Analiz: ortalama 1,39 N lg N; en kötü N²/2 → karıştır!
  • İyileştirmeler: küçük parçalara insertion, üçün ortancası.
  • 3 yollu bölümleme: az farklı anahtarda neredeyse doğrusal.
  • Quickselect: medyan, k en yakın, %1 low — ortalama doğrusal.
  • 🎮 Bölümleme: canlılar başa, ölüler sona.
  • ⚙️ Saldırılar ve introsort; kütüphaneler ne kullanıyor.

Alıştırmalar 🏋️

  1. Kâğıt-kalem: E A S Y Q U E S T I O N dizisini (karıştırmadan) bölümleyin ve quicksort iz tablosunu çıkarın.
  2. Quickselect ile 100 düşman arasından en yakın 5’ini bulun (k = 4’ü seçin; solundakiler de en yakınlardır!). Sonra sadece o 5’i sıralayın.
  3. Unity’de 1000 karelik süreleri bir dizide tutup ekranda ortalama FPS, medyan ve %1 low gösteren bir “performans paneli” yapın.
  4. Envanteri nadirliğe göre 3 yollu bölümleme ile tek geçişte gruplayın (efsanevi | epik | diğer).
  5. Sıralı girdide karıştırmasız quicksort’un özyineleme derinliğini ölçün. N = 10.000’de C# ne yapıyor?
  6. 🤖 Bir YZ asistanından quicksort isteyin. Pivotu nasıl seçti? Karıştırma ya da rastgele pivot var mı? Sıralı ve “hepsi eşit” girdilerde test edin.

Kaynaklar: videolar 🎬

Kaynaklar: okuma 📚

NEXT LEVEL ▶
Ağaçlar ve İkili Arama Ağaçları
Rastgele BST ile quicksort aynı matematiği paylaşıyor — bakalım neden!
SONRAKİ SUNUM ▶