首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

堆排序算法:原理、實現與性能分析

     編輯:關於C語言

堆排序是原地、O(n log n) 最壞情況保證的比較排序算法,利用二叉堆數據結構實現,是系統級排序的常見選擇。

核心概念

  • 大頂堆:父節點 ≥ 子節點,根節點為最大值
  • 小頂堆:父節點 ≤ 子節點,根節點為最小值
  • 堆化:將任意數組調整為滿足堆性質的結構

算法流程

  1. 建堆:從最後一個非葉節點開始,自下而上調用 heapify
  2. 排序:重複「交換堆頂與末尾元素、減小堆大小、重新堆化」

關鍵操作:Heapify

void heapify(int arr[], int n, int i) {
    int largest = i;
    int left = 2*i + 1;
    int right = 2*i + 2;
    
    if (left < n && arr[left] > arr[largest]) largest = left;
    if (right < n && arr[right] > arr[largest]) largest = right;
    
    if (largest != i) {
        swap(&arr[i], &arr[largest]);
        heapify(arr, n, largest);  // 遞歸向下調整
    }
}

完整 C 實現

#include <stdio.h>

void swap(int *a, int *b) {
    int t = *a; *a = *b; *b = t;
}

void heapify(int arr[], int n, int i) {
    int largest = i;
    int l = 2*i + 1, r = 2*i + 2;
    if (l < n && arr[l] > arr[largest]) largest = l;
    if (r < n && arr[r] > arr[largest]) largest = r;
    if (largest != i) {
        swap(&arr[i], &arr[largest]);
        heapify(arr, n, largest);
    }
}

void heap_sort(int arr[], int n) {
    // 建堆:從最後非葉節點開始
    for (int i = n/2 - 1; i >= 0; i--)
        heapify(arr, n, i);
    
    // 排序:逐個提取堆頂
    for (int i = n-1; i > 0; i--) {
        swap(&arr[0], &arr[i]);  // 最大值移至末尾
        heapify(arr, i, 0);      // 縮小堆範圍並調整
    }
}

int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr)/sizeof(arr[0]);
    heap_sort(arr, n);
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    return 0;
}

複雜度分析

指標複雜度說明
時間(最好/平均/最壞)O(n log n)建堆 O(n),n 次 heapify 各 O(log n)
空間O(1)原地排序,遞歸棧可轉迭代
穩定性不穩定相等元素相對位置可能改變

工程優化技巧

  • 迭代替代遞歸:消除函數調用開銷,避免棧溢出
  • 底層優化:對小數組切換插入排序(如 n < 16)
  • 緩存友好:順序訪問模式利於 CPU 緩存

應用場景

  • 嵌入式系統:固定 O(n log n)、O(1) 空間
  • 實時系統:最壞情況時間可預測
  • Top-K 問題:建最小堆維護前 K 大元素
  • 外部排序:作為內部排序子程序

堆排序雖不如快速排序常數因子小,但其確定性能使其在關鍵系統中不可替代。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved