Quick Sort
Son güncelleme
Quicksort, bir "pivot" etrafında sıralayan bir böl ve yönet algoritmasıdır. Bir pivot eleman seçer, ardından diziyi öyle bölümler ki tüm küçük değerler önce, tüm büyük değerler sonra gelir - bu da pivotu nihai sıralı konumuna kilitler. Sonra sol ve sağ bölümler üzerinde özyineleme yapar. Bu görselleştirme, son elemanı pivot olarak kullanan Lomuto şemasını kullanır. Bölümlemeyi ve pivot yerleşimini izlemek için oynat'a basın.
Quicksort, iyi önbellek davranışı ve yerinde bölümleme sayesinde pratikte genellikle en hızlı genel amaçlı sıralamadır ve ortalaması O(n log n)'dir. En kötü durumu O(n²)'dir (örneğin kötü bir pivot seçimiyle zaten sıralı bir dizi); üç-medyan veya rastgeleleştirme gibi iyi pivot stratejileri bunu önler.
Zaman ve alan karmaşıklığı
| Durum | Karmaşıklık | Notlar |
|---|---|---|
| En iyi durum | O(n log n) | Dengeli bölümler |
| Ortalama durum | O(n log n) | Rastgele sıra |
| En kötü durum | O(n²) | Sürekli dengesiz pivotlar |
| Alan | O(log n) | Özyineleme yığını (yerinde bölümleme) |
| Kararlı | Hayır | Bölümleme takasları eşit elemanları yeniden sıralar |
Adım adım
| Adım | Ne olur |
|---|---|
| 1 | Bir pivot seçin (burada, aralığın son elemanı). |
| 2 | Bölümleme: pivottan küçük tüm elemanları soluna taşıyın. |
| 3 | Pivotu sınıra takas edin - artık nihai konumundadır. |
| 4 | Sol bölüme özyinelemeli olarak quicksort uygulayın. |
| 5 | Sağ bölüme özyinelemeli olarak quicksort uygulayın. |
Çözümlü örnek
[5, 2, 4, 1] dizisini Lomuto şemasıyla (son eleman pivot) sıralama:
| Geçiş | Dizi | İşlem |
|---|---|---|
| Başlangıç | [5, 2, 4, 1] | Tüm aralığı bölümle; pivot 1 (son eleman). |
| 1 | [1, 2, 4, 5] | 1'den küçük hiçbir şey yok, bu yüzden 1'i 0 indisine takas edin; pivot 1 artık nihaidir. [2, 4, 5] üzerinde sağa özyinele. |
| 2 | [1, 2, 4, 5] | [2, 4, 5]'i pivot 5 ile bölümle; hem 2 hem 4 daha küçük, bu yüzden 5 sonda kalır ve nihaidir. [2, 4] üzerinde sola özyinele. |
| 3 | [1, 2, 4, 5] | [2, 4]'ü pivot 4 ile bölümle; 2 daha küçük, bu yüzden 4 yerinde kalır ve nihaidir. 2 tek bir elemandır, bu yüzden zaten sıralıdır. |
| Bitti | [1, 2, 4, 5] | Her pivot yerine kilitlenir; dizi sıralanmıştır. |
Quicksort ne zaman kullanılır
| Şu durumda kullanın | Şu durumda kaçının |
|---|---|
| Küçük sabit çarpanlı, hızlı ve genel amaçlı bir bellek içi sıralamaya ihtiyacınız olduğunda. | Garantili O(n log n) en kötü durum süresine ihtiyacınız olduğunda (heap sort veya merge sort kullanın). |
Bellek kısıtlıysa - bölümleme yerinde yapılır ve yalnızca O(log n) yığın alanı gerektirir. | Eşit anahtarların sırasını koruyan kararlı bir sıralamaya ihtiyacınız olduğunda. |
| Veri rastgele veya bilinmeyen sırada ise ve rastgele ya da üç-medyan pivot kullanıyorsanız. | Girdi zaten sıralı veya neredeyse sıralıysa ve pivot sabitse, O(n²)'yi tetikler. |
| İyi önbellek yerelliği önemliyse, çünkü quicksort belleğe sıralı erişir. | Bağlı liste sıralıyorsanız; burada merge sort, quicksort'un dayandığı rastgele erişimden kaçınır. |
Quick Sort kodu
Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir Quick Sort uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.
Python ile Quick Sort kodu
1def quick_sort(a, low=0, high=None):2 if high is None:3 high = len(a) - 14 if low < high:5 p = partition(a, low, high)6 quick_sort(a, low, p - 1)7 quick_sort(a, p + 1, high)8 return a9
10
11def partition(a, low, high):12 # Lomuto partition: everything < pivot moves left of it13 pivot = a[high]14 i = low15 for j in range(low, high):16 if a[j] < pivot:17 a[i], a[j] = a[j], a[i]18 i += 119 a[i], a[high] = a[high], a[i]20 return i21
22
23nums = [10, 7, 8, 9, 1, 5]24print("Before:", nums)25quick_sort(nums)26print("After: ", nums)JavaScript ile Quick Sort kodu
1function quickSort(a, lo = 0, hi = a.length - 1) {2 if (lo >= hi) return a;3 const p = partition(a, lo, hi);4 quickSort(a, lo, p - 1);5 quickSort(a, p + 1, hi);6 return a;7}8
9// Lomuto partition: last element is the pivot10function partition(a, lo, hi) {11 const pivot = a[hi];12 let i = lo;13 for (let j = lo; j < hi; j++) {14 if (a[j] < pivot) {15 [a[i], a[j]] = [a[j], a[i]];16 i++;17 }18 }19 [a[i], a[hi]] = [a[hi], a[i]];20 return i;21}22
23const data = [5, 2, 9, 1, 7, 3];24console.log("Before:", data);25console.log("Sorted:", quickSort([...data]));Java ile Quick Sort kodu
1import java.util.Arrays;2
3public class Main {4 static void quickSort(int[] arr, int low, int high) {5 if (low >= high) return;6 int p = partition(arr, low, high);7 quickSort(arr, low, p - 1);8 quickSort(arr, p + 1, high);9 }10
11 // Lomuto partition: last element is the pivot12 static int partition(int[] arr, int low, int high) {13 int pivot = arr[high];14 int i = low - 1;15 for (int j = low; j < high; j++) {16 if (arr[j] < pivot) swap(arr, ++i, j);17 }18 swap(arr, i + 1, high);19 return i + 1;20 }21
22 static void swap(int[] arr, int a, int b) {23 int tmp = arr[a];24 arr[a] = arr[b];25 arr[b] = tmp;26 }27
28 public static void main(String[] args) {29 int[] arr = {10, 7, 8, 9, 1, 5};30 System.out.println("Before: " + Arrays.toString(arr));31 quickSort(arr, 0, arr.length - 1);32 System.out.println("After: " + Arrays.toString(arr));33 }34}C++ ile Quick Sort kodu
1#include <iostream>2#include <utility>3#include <vector>4
5void printVec(const std::vector<int>& a) {6 for (int x : a) std::cout << x << " ";7 std::cout << "\n";8}9
10// Lomuto partition: place the pivot in its final position11int partition(std::vector<int>& a, int lo, int hi) {12 int pivot = a[hi];13 int i = lo;14 for (int j = lo; j < hi; ++j) {15 if (a[j] < pivot) std::swap(a[i++], a[j]);16 }17 std::swap(a[i], a[hi]);18 return i;19}20
21void quickSort(std::vector<int>& a, int lo, int hi) {22 if (lo >= hi) return;23 int p = partition(a, lo, hi);24 quickSort(a, lo, p - 1);25 quickSort(a, p + 1, hi);26}27
28int main() {29 std::vector<int> data = {10, 7, 8, 9, 1, 5};30 std::cout << "Before: ";31 printVec(data);32 quickSort(data, 0, static_cast<int>(data.size()) - 1);33 std::cout << "After: ";34 printVec(data);35 return 0;36}C ile Quick Sort kodu
1#include <stdio.h>2
3void printArr(const int a[], int n) {4 for (int i = 0; i < n; i++) printf("%d ", a[i]);5 printf("\n");6}7
8void swap(int* x, int* y) {9 int tmp = *x;10 *x = *y;11 *y = tmp;12}13
14// Lomuto partition: place the pivot in its final position15int partition(int a[], int lo, int hi) {16 int pivot = a[hi];17 int i = lo;18 for (int j = lo; j < hi; j++) {19 if (a[j] < pivot) swap(&a[i++], &a[j]);20 }21 swap(&a[i], &a[hi]);22 return i;23}24
25void quickSort(int a[], int lo, int hi) {26 if (lo >= hi) return;27 int p = partition(a, lo, hi);28 quickSort(a, lo, p - 1);29 quickSort(a, p + 1, hi);30}31
32int main(void) {33 int data[] = {10, 7, 8, 9, 1, 5};34 int n = sizeof(data) / sizeof(data[0]);35 printf("Before: ");36 printArr(data, n);37 quickSort(data, 0, n - 1);38 printf("After: ");39 printArr(data, n);40 return 0;41}Quick Sort SSS
Quicksort'un zaman karmaşıklığı nedir?
O(n log n)'dir ve en iyi durumda O(n log n)'dir, ancak bölümler sürekli dengesiz olduğunda en kötü durumda O(n²)'ye düşer. Rastgele veya üç-medyan pivotlar en kötü durumu çok olası kılmaz.Quicksort kararlı mı?
Quicksort neden genellikle merge sort'tan daha hızlıdır?
O(n log n) sınırına eşit olur ancak O(n) tampon ve daha fazla veri hareketi için bedel öder.Quicksort mu merge sort mu - hangisini kullanmalıyım?
O(n log n) en kötü durum ya da RAM'e sığmayan bağlı liste veya harici veri sıralaması gerektiğinde merge sort'u seçin.Quicksort sıralı bir dizide neden O(n²) olur?
log n yerine n özyineleme seviyesi üretir. Pivotu rastgele veya üç-medyan ile seçmek bu deseni kırar ve O(n log n) davranışını geri getirir.