Quick Sort Algoritması

Quick Sort Açıklaması

Quick Sort, "Böl ve Fethet" (Divide and Conquer) paradigmasını kullanan hızlı ve verimli bir sıralama algoritmasıdır. Tony Hoare tarafından 1960 yılında geliştirilmiştir ve adını hızlı çalışmasından almıştır. ## Çalışma Prensibi: 1. **Pivot Seçimi**: Diziden bir "pivot" eleman seçilir. 2. **Bölme (Partitioning)**: Dizi, pivot etrafında yeniden düzenlenir: - Pivottan küçük elemanlar pivotun soluna - Pivottan büyük elemanlar pivotun sağına yerleştirilir 3. **Özyineleme (Recursion)**: Pivotun solundaki ve sağındaki alt diziler için aynı işlem özyinelemeli olarak tekrarlanır. 4. **Birleştirme**: Quick Sort'ta açık bir birleştirme adımı yoktur, alt diziler yerinde sıralanır. ## Önemli Özellikler: 1. **Yerinde Sıralama**: Genellikle ekstra O(log n) yığın belleği dışında ek bellek kullanmaz. 2. **Kararsız Sıralama**: Eşit değere sahip elemanların göreceli sırası korunmayabilir. 3. **Uyarlanabilir**: Pivot seçimine bağlı olarak özelleştirilebilir ve optimize edilebilir. 4. **Pratik Verimlilik**: Ortalama durumda O(n log n) zaman karmaşıklığı ile çoğu durumda diğer O(n log n) algoritmalardan daha hızlı çalışır. Quick Sort, özellikle büyük veri setleri için ve hızın önemli olduğu durumlarda tercih edilen bir algoritmadır. Ancak, en kötü durumda O(n²) performans gösterebilir, bu nedenle pivot seçimi kritik öneme sahiptir.

Kod Örnekleri

Quick Sort algoritmasının farklı programlama dillerindeki uygulamaları aşağıda verilmiştir. Her örnek, algoritmanın optimize edilmiş versiyonunu içerir ve detaylı açıklamalarla sunulmuştur.

Quick Sort - JavaScript
1/**
2 * Quick Sort implementation for JavaScript arrays
3 * @param {Array} arr - The array to sort
4 * @returns {Array} - A new sorted array
5 */
6function quickSort(arr) {
7 // Create a copy to avoid modifying the original array
8 const result = [...arr];
9
10 // Helper recursive function that performs the sorting
11 const sort = (arr, low, high) => {
12 if (low < high) {
13 // Find the partition index
14 const pivotIndex = partition(arr, low, high);
15
16 // Recursively sort elements before and after the pivot
17 sort(arr, low, pivotIndex - 1);
18 sort(arr, pivotIndex + 1, high);
19 }
20 };
21
22 // Helper function to partition the array around a pivot
23 const partition = (arr, low, high) => {
24 // Choose the rightmost element as pivot
25 const pivot = arr[high];
26
27 // Index of smaller element
28 let i = low - 1;
29
30 // Compare each element with pivot
31 for (let j = low; j < high; j++) {
32 // If current element is smaller than the pivot
33 if (arr[j] < pivot) {
34 i++;
35 // Swap elements
36 [arr[i], arr[j]] = [arr[j], arr[i]];
37 }
38 }
39
40 // Swap the pivot element with the element at (i+1)
41 [arr[i + 1], arr[high]] = [arr[high], arr[i + 1]];
42
43 // Return the pivot position
44 return i + 1;
45 };
46
47 // Call the sorting function on the entire array
48 sort(result, 0, result.length - 1);
49
50 return result;
51}

Kendi Verilerinizle Test Edin

Aşağıya kendi verilerinizi girerek Quick Sort algoritmasını test edebilirsiniz. Virgülle ayrılmış sayılar girin (örn: 5,3,8,4,2) veya rastgele bir dizi oluşturun.

Quick Sort Demo

Verdiğiniz dizi Quick Sort algoritması ile sıralanacaktır.

Sıralanmış Dizi: null

Not: Quick Sort ortalama durumda O(n log n) karmaşıklığa sahiptir ve çoğu pratik uygulamada oldukça hızlıdır.

Algoritma Analizi

Zaman ve Alan Karmaşıklığı

Zaman Karmaşıklığı

  • En İyi Durum: O(n log n) - Her bölünmede pivot, diziyi iki eşit parçaya böldüğünde oluşur.
  • Ortalama Durum: O(n log n) - Rastgele pivot seçiminde ortalama karmaşıklık.
  • En Kötü Durum: O(n²) - Pivot, sürekli olarak en küçük veya en büyük eleman olduğunda oluşur.

Alan Karmaşıklığı

O(log n) - Özyinelemeli çağrılar için yığın belleği kullanır. En kötü durumda, yığın derinliği O(n) olabilir, ancak ortalamada O(log n)'dir.

Kararlılık (Stability)

Quick Sort kararsız bir algoritmadır. Pivot etrafında elemanların yeniden düzenlenmesi sırasında, eşit değere sahip elemanların orijinal sırası değişebilir.

Avantajlar ve Dezavantajlar

Avantajlar

  • Pratik uygulamalarda genellikle çok hızlıdır.
  • Yerinde sıralama yapar, minimum ekstra bellek kullanır.
  • Önbellek dostu bir erişim modeline sahiptir.
  • Farklı pivot seçim stratejileri ile optimize edilebilir.
  • Çoğu programlama dilinde dahili sıralama algoritması olarak kullanılır.

Dezavantajlar

  • En kötü durumda O(n²) zaman karmaşıklığına sahiptir.
  • Kararsız bir algoritma olduğundan, eşit değerli elemanların sırası değişebilir.
  • Merge Sort gibi algoritmalara göre daha karmaşık bir yapıya sahiptir.
  • Kötü pivot seçimleri, özellikle zaten sıralı dizilerde, performansı önemli ölçüde düşürebilir.

Quick Sort Nasıl Çalışır?

Aşağıda, Quick Sort'un [7, 2, 1, 6, 8, 5, 3, 4] dizisini sıralama adımları gösterilmiştir:

Adım Adım Quick Sort

Başlangıç Dizisi:

[7, 2, 1, 6, 8, 5, 3, 4]

Pivot olarak son eleman seçilir: 4

1. Bölme (İlk Düzey):

4'ten küçük elemanlar sola, büyük elemanlar sağa yerleştirilir:

[2, 1, 3, 4, 8, 5, 7, 6]

Pivot (4) artık doğru konumunda ve dizi iki alt parçaya bölünür.

2. Bölme (Sol Alt Dizi):

Sol alt dizide ([2, 1, 3]) pivot olarak 3 seçilir:

[2, 1, 3, 4, 8, 5, 7, 6]

3'ten küçük elemanlar sola yerleştirilir:

[2, 1, 3, 4, 8, 5, 7, 6]

3. Bölme (Sol Alt Dizinin Sol Alt Dizisi):

[2, 1] alt dizisinde pivot olarak 1 seçilir:

[1, 2, 3, 4, 8, 5, 7, 6]

1'den küçük eleman olmadığı için, sadece sağında 2 kalır.

4. Bölme (Sağ Alt Dizi):

Sağ alt dizide ([8, 5, 7, 6]) pivot olarak 6 seçilir:

[1, 2, 3, 4, 5, 6, 7, 8]

6'dan küçük elemanlar (5) sola, büyük elemanlar (7, 8) sağa yerleştirilir.

5. Bölme (Sağ Alt Dizinin Alt Dizileri):

Kalan alt diziler [5] ve [7, 8] için aynı işlemler tekrarlanır:

[1, 2, 3, 4, 5, 6, 7, 8]

Sonuç: Tamamen Sıralanmış Dizi

[1, 2, 3, 4, 5, 6, 7, 8]

Pivot Seçim Stratejileri

Quick Sort'un performansı büyük ölçüde pivot seçimine bağlıdır. İşte yaygın pivot seçim stratejileri:

İlk/Son Eleman Pivot

Dizinin ilk veya son elemanının pivot olarak seçilmesi en basit stratejilerdendir. Ancak, zaten sıralı veya ters sıralı dizilerde en kötü durum O(n²) performansına neden olabilir.

pivot = arr[high]; // Son eleman

Ortanca Eleman Pivot

Dizinin ortasındaki elemanı pivot olarak seçmek, sıralı dizilerde daha iyi performans sağlar. Ancak, her alt dizi için ortanca elemanı bulmak da ek işlem gerektirir.

pivot = arr[Math.floor((low + high) / 2)];

Rastgele Pivot

Diziden rastgele bir elemanı pivot olarak seçmek, en kötü durum performansının olasılığını düşürür. Bu yaklaşım, çeşitli veri setlerinde genellikle iyi performans gösterir.

const randomIndex = low + Math.floor(Math.random() * (high - low + 1)); pivot = arr[randomIndex];

Üçlünün Ortancası (Median of Three)

Dizinin ilk, orta ve son elemanından ortanca değeri pivot olarak seçmek, çoğu pratik uygulamada iyi sonuçlar verir. Bu strateji, rastgele ve deterministik yaklaşımların avantajlarını birleştirir.

const mid = Math.floor((low + high) / 2); // İlk, orta ve son elemanın ortancasını bul if (arr[mid] < arr[low]) [arr[low], arr[mid]] = [arr[mid], arr[low]]; if (arr[high] < arr[low]) [arr[low], arr[high]] = [arr[high], arr[low]]; if (arr[mid] < arr[high]) [arr[mid], arr[high]] = [arr[high], arr[mid]]; pivot = arr[high];

Quick Sort ve Diğer Algoritmalar

Quick Sort ile diğer popüler sıralama algoritmalarının karşılaştırması:

ÖzellikQuick SortMerge SortHeap SortInsertion Sort
En İyi DurumO(n log n)O(n log n)O(n log n)O(n)
Ortalama DurumO(n log n)O(n log n)O(n log n)O(n²)
En Kötü DurumO(n²)O(n log n)O(n log n)O(n²)
Alan KarmaşıklığıO(log n)O(n)O(1)O(1)
KararlılıkKararsızKararlıKararsızKararlı
Önbellek DostuYüksekOrtaDüşükYüksek
Pratik PerformansÇok İyiİyiİyiKüçük veri setleri için iyi
Tercih Edilme DurumuGenel amaçlı, ortalama performansın önemli olduğu durumlarKararlılık ve güvenilir performans gerektiğindeBellek sınırlı ortamlardaKüçük veya kısmen sıralı dizilerde

Quick Sort, pratik uygulamalarda genellikle en iyi performansı gösteren sıralama algoritmasıdır. Önbellek dostu yapısı ve minimal bellek kullanımı nedeniyle çoğu programlama dilinde dahili sıralama algoritması olarak tercih edilir. Ancak, kararsız oluşu ve en kötü durum performansı göz önüne alınmalıdır.

İlgili Algoritmalar

Quick Sort ile ilişkili veya benzer algoritmalar:

Dual-Pivot Quick Sort

İki pivot kullanan bir Quick Sort varyasyonu. Java'nın Arrays.sort() uygulamasında kullanılır ve genellikle standart Quick Sort'tan daha hızlıdır.

Introsort

Quick Sort, Heap Sort ve Insertion Sort'u birleştiren hibrit bir algoritma. En kötü durumu önlemek için, özyineleme derinliği belirli bir eşiği aştığında Heap Sort'a geçiş yapar.

Quick Select

Quick Sort'un bölme mekanizmasını kullanarak, sıralanmamış bir diziden k. en küçük (veya en büyük) elemanı bulan bir algoritma. Ortalama O(n) karmaşıklığa sahiptir.

Quick Sort

Böl ve Fethet stratejisini kullanan hızlı ve verimli bir sıralama algoritması.

Avantajlar

  • Pratik uygulamalarda genellikle çok hızlıdır
  • Yerinde sıralama yapar, minimum ekstra bellek kullanır
  • Önbellek dostu bir erişim modeline sahiptir
  • Pivot seçim stratejileri ile optimize edilebilir
  • Rastgele erişimli veri yapıları için idealdir

Dezavantajlar

  • En kötü durumda O(n²) zaman karmaşıklığına sahiptir
  • Kararsız bir sıralama algoritmasıdır
  • Pivot seçimi, performansı önemli ölçüde etkiler
  • Bağlı listeler gibi ardışıl erişimli veri yapıları için verimli değildir