Heap Sort
Son güncelleme
Heap sort diziyi bir ikili yığın (heap) olarak ele alır. Önce bir max-heap oluşturur, böylece en büyük eleman kökte (indeks 0) yer alır. Ardından kökü sıralanmamış son elemanla tekrar tekrar takas eder - en büyüğü yerine sabitler - ve heap özelliğini yeniden sağlamak için yeni kökü aşağı sızdırır. Yığının oluşturulmasını ve çıkarmaları izlemek için yukarıdaki oynat düğmesine basın.
Heap sort merge sort gibi O(n log n) zamanı garanti eder, ancak yalnızca O(1) ek alanla yerinde sıralar. Kararlı değildir ve quicksort'a göre daha kötü önbellek davranışı gösterme eğilimindedir; bu yüzden hem garantili bir sınır hem de sabit bellek önemli olduğunda sıkça tercih edilir.
Zaman ve alan karmaşıklığı
| Durum | Karmaşıklık | Notlar |
|---|---|---|
| En iyi durum | O(n log n) | Oluşturma + n çıkarma |
| Ortalama durum | O(n log n) | Rastgele sıra |
| En kötü durum | O(n log n) | Garantili |
| Alan | O(1) | Yerinde |
| Kararlı | Hayır | Aşağı sızdırma eşit elemanları yeniden sıralar |
Adım adım
| Adım | Ne olur |
|---|---|
| 1 | Diziden bir max-heap oluştur (son ebeveynden başlayarak aşağı sızdır). |
| 2 | Kökü (en büyüğü) yığının son elemanıyla takas et. |
| 3 | Yığını bir küçült - o son yuva artık sıralı. |
| 4 | Max-heap özelliğini geri getirmek için yeni kökü aşağı sızdır. |
| 5 | Yığında tek eleman kalana kadar tekrarla. |
Çözümlü örnek
[3, 1, 6, 5, 2, 4] sıralanıyor. | çubuğu küçülen yığın ile sıralı kuyruk arasındaki sınırı gösterir:
| Geçiş | Dizi | İşlem |
|---|---|---|
| Yığın oluştur | [6, 5, 4, 1, 2, 3] | Max-heap oluşturmak için son ebeveynden aşağı sızdır; 6 artık kökte. |
| 1 | [5, 3, 4, 1, 2 | 6] | Kök 6 ile son yuvayı takas et, yığını küçült ve 3'ü aşağı sızdır. |
| 2 | [4, 3, 2, 1 | 5, 6] | Kök 5'i çıkar, ardından 2'yi aşağı sızdır ki 4 köke yükselsin. |
| 3 | [3, 1, 2 | 4, 5, 6] | Kök 4'ü çıkar, ardından 1'i aşağı sızdır ki 3 köke yükselsin. |
| 4 | [2, 1 | 3, 4, 5, 6] | Kök 3'ü çıkar; 2 zaten heap özelliğini sağlıyor. |
| 5 | [1 | 2, 3, 4, 5, 6] | Kök 2'yi çıkar; tek eleman kaldı, yani dizi sıralı. |
Heap sort ne zaman kullanılır
| Kullanın | Kullanmayın |
|---|---|
O(n²) riski olmadan garantili O(n log n) en kötü durum gerektiğinde. | Eşit anahtarların sırasını koruyan kararlı bir sıralama gerektiğinde. |
Bellek kısıtlıysa - yalnızca O(1) ek alanla yerinde sıralar. | Önbellek performansı önemliyse ve veri belleğe sığıyorsa - quicksort genellikle daha hızlıdır. |
| Veri üzerinde zaten bir yığın (örneğin öncelik kuyruğu) tutuyorsanız. | En az karşılaştırmayı istiyorsanız - merge sort ve quicksort pratikte genellikle daha az yapar. |
| Güvenilmeyen girdi quicksort'un en kötü durumunu tetikleyebilir ve rastgeleleştiremiyorsanız. | Veri neredeyse sıralıysa - insertion sort onun üzerinde neredeyse doğrusal zamanda çalışır. |
Heap Sort kodu
Python, JavaScript, Java, C++, C dillerinde temiz ve çalıştırılabilir bir Heap Sort uygulaması. Bir dil seçin, kodu kopyalayın veya Coddy Playground'da hazır yüklenmiş olarak açın.
Python ile Heap Sort kodu
1def heap_sort(a):2 n = len(a)3 # Build a max-heap, deepest parent first4 for i in range(n // 2 - 1, -1, -1):5 sift_down(a, i, n)6 # Repeatedly move the max to the end and shrink the heap7 for end in range(n - 1, 0, -1):8 a[0], a[end] = a[end], a[0]9 sift_down(a, 0, end)10 return a11
12
13def sift_down(a, i, size):14 while True:15 largest = i16 left, right = 2 * i + 1, 2 * i + 217 if left < size and a[left] > a[largest]:18 largest = left19 if right < size and a[right] > a[largest]:20 largest = right21 if largest == i:22 return23 a[i], a[largest] = a[largest], a[i]24 i = largest25
26
27nums = [12, 11, 13, 5, 6, 7]28print("Before:", nums)29heap_sort(nums)30print("After: ", nums)JavaScript ile Heap Sort kodu
1function heapSort(a) {2 const n = a.length;3 // Build a max-heap, then repeatedly move the max to the end4 for (let i = Math.floor(n / 2) - 1; i >= 0; i--) siftDown(a, i, n);5 for (let end = n - 1; end > 0; end--) {6 [a[0], a[end]] = [a[end], a[0]];7 siftDown(a, 0, end);8 }9 return a;10}11
12function siftDown(a, i, size) {13 while (true) {14 const left = 2 * i + 1;15 const right = 2 * i + 2;16 let largest = i;17 if (left < size && a[left] > a[largest]) largest = left;18 if (right < size && a[right] > a[largest]) largest = right;19 if (largest === i) return;20 [a[i], a[largest]] = [a[largest], a[i]];21 i = largest;22 }23}24
25const data = [5, 2, 9, 1, 7, 3];26console.log("Before:", data);27console.log("Sorted:", heapSort([...data]));Java ile Heap Sort kodu
1import java.util.Arrays;2
3public class Main {4 static void heapSort(int[] arr) {5 int n = arr.length;6 // Build a max-heap, deepest parent first7 for (int i = n / 2 - 1; i >= 0; i--) siftDown(arr, i, n);8 // Repeatedly move the max to the end and shrink the heap9 for (int end = n - 1; end > 0; end--) {10 swap(arr, 0, end);11 siftDown(arr, 0, end);12 }13 }14
15 static void siftDown(int[] arr, int i, int size) {16 while (true) {17 int largest = i, l = 2 * i + 1, r = 2 * i + 2;18 if (l < size && arr[l] > arr[largest]) largest = l;19 if (r < size && arr[r] > arr[largest]) largest = r;20 if (largest == i) return;21 swap(arr, i, largest);22 i = largest;23 }24 }25
26 static void swap(int[] arr, int a, int b) {27 int tmp = arr[a];28 arr[a] = arr[b];29 arr[b] = tmp;30 }31
32 public static void main(String[] args) {33 int[] arr = {12, 11, 13, 5, 6, 7};34 System.out.println("Before: " + Arrays.toString(arr));35 heapSort(arr);36 System.out.println("After: " + Arrays.toString(arr));37 }38}C++ ile Heap 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
10void siftDown(std::vector<int>& a, int n, int i) {11 while (true) {12 int largest = i, l = 2 * i + 1, r = 2 * i + 2;13 if (l < n && a[l] > a[largest]) largest = l;14 if (r < n && a[r] > a[largest]) largest = r;15 if (largest == i) return;16 std::swap(a[i], a[largest]);17 i = largest;18 }19}20
21void heapSort(std::vector<int>& a) {22 int n = static_cast<int>(a.size());23 // Build a max-heap in place24 for (int i = n / 2 - 1; i >= 0; --i) siftDown(a, n, i);25 // Repeatedly move the max to the end and shrink the heap26 for (int end = n - 1; end > 0; --end) {27 std::swap(a[0], a[end]);28 siftDown(a, end, 0);29 }30}31
32int main() {33 std::vector<int> data = {12, 11, 13, 5, 6, 7};34 std::cout << "Before: ";35 printVec(data);36 heapSort(data);37 std::cout << "After: ";38 printVec(data);39 return 0;40}C ile Heap 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 siftDown(int a[], int n, int i) {9 while (1) {10 int largest = i, l = 2 * i + 1, r = 2 * i + 2;11 if (l < n && a[l] > a[largest]) largest = l;12 if (r < n && a[r] > a[largest]) largest = r;13 if (largest == i) return;14 int tmp = a[i];15 a[i] = a[largest];16 a[largest] = tmp;17 i = largest;18 }19}20
21void heapSort(int a[], int n) {22 // Build a max-heap in place23 for (int i = n / 2 - 1; i >= 0; i--) siftDown(a, n, i);24 // Repeatedly move the max to the end and shrink the heap25 for (int end = n - 1; end > 0; end--) {26 int tmp = a[0];27 a[0] = a[end];28 a[end] = tmp;29 siftDown(a, end, 0);30 }31}32
33int main(void) {34 int data[] = {12, 11, 13, 5, 6, 7};35 int n = sizeof(data) / sizeof(data[0]);36 printf("Before: ");37 printArr(data, n);38 heapSort(data, n);39 printf("After: ");40 printArr(data, n);41 return 0;42}Heap Sort SSS
Heap sort'un zaman karmaşıklığı nedir?
O(n log n)'dir. Yığını oluşturmak O(n)'dir ve n çıkarmanın her biri O(log n) maliyetindedir. O(1) ek alan kullanır.Heap sort kararlı mıdır?
Heap sort'u ne zaman kullanmalıyım?
O(1) ek bellekle garantili O(n log n) en kötü durum gerektiğinde heap sort'u kullanın. Quicksort'un O(n²) riskinden, merge sort'un O(n) arabelleği olmadan kaçınır; bunun bedeli kararlılık ve önbellek performansıdır.Heap sort ile quicksort arasındaki fark nedir?
O(n²) en kötü durumu varken heap sort O(n log n) garanti eder. Pratikte quicksort daha iyi önbellek yerelliği ve daha az takas nedeniyle genellikle daha hızlıdır, bu yüzden heap sort esas olarak en kötü durum sınırının garanti edilmesi gerektiğinde tercih edilir.