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

八大經典排序算法 C++ 模板實現全解析

     編輯:關於C++

排序算法綜述

本文提供八種常用排序算法的 C++ 泛型實現,涵蓋從基礎的 O(n²) 算法到高效的 O(n log n) 算法,以及非比較排序的基數排序。所有算法均以模板形式實現,支援任意可比較類型。

算法分類與複雜度對比

算法平均時間最壞時間空間穩定性
插入排序O(n²)O(n²)O(1)穩定
冒泡排序O(n²)O(n²)O(1)穩定
選擇排序O(n²)O(n²)O(1)不穩定
希爾排序O(n1.3)O(n²)O(1)不穩定
快速排序O(n log n)O(n²)O(log n)不穩定
歸並排序O(n log n)O(n log n)O(n)穩定
堆排序O(n log n)O(n log n)O(1)不穩定
LSD 基數排序O(d(n+r))O(d(n+r))O(n+r)穩定

核心實現亮點

快速排序:雙向掃描分區

template <class T>
int _partition(T a[], int left, int right) {
    T pivot = a[left];
    while (left < right) {
        while (left < right && a[right] >= pivot) --right;
        a[left] = a[right];
        while (left < right && a[left] <= pivot) ++left;
        a[right] = a[left];
    }
    a[left] = pivot;
    return left;
}

歸並排序:輔助數組合併

template <class T>
void _merge(T a[], int left, int mid, int right) {
    int len = right - left + 1;
    T* tmp = new T[len];
    for (int i = 0, j = left; i < len; ++i, ++j) tmp[i] = a[j];
    
    int i = 0, j = mid - left + 1, k = left;
    while (i <= mid - left && j <= len - 1) {
        a[k++] = (tmp[i] < tmp[j]) ? tmp[i++] : tmp[j++];
    }
    while (i <= mid - left) a[k++] = tmp[i++];
    while (j <= len - 1) a[k++] = tmp[j++];
    delete[] tmp;
}

堆排序:自底向上建堆 + 下沉調整

template <class T>
void adjust_node(T a[], int n, int i) {
    int largest = i;
    int l = 2 * i + 1, r = 2 * i + 2;
    if (l < n && a[l] > a[largest]) largest = l;
    if (r < n && a[r] > a[largest]) largest = r;
    if (largest != i) {
        swap(a[i], a[largest]);
        adjust_node(a, n, largest);
    }
}

LSD 基數排序:計數排序作為子程序

template <class T>
void lst_radix_sort(T a[], int n, int radix, int distance) {
    T* tmp = new T[n];
    int* cnt = new int[radix];
    int div = 1;
    for (int d = 0; d < distance; ++d, div *= radix) {
        fill(cnt, cnt + radix, 0);
        for (int i = 0; i < n; ++i) cnt[(a[i] / div) % radix]++;
        for (int i = 1; i < radix; ++i) cnt[i] += cnt[i-1];
        for (int i = n - 1; i >= 0; --i) {
            int idx = (a[i] / div) % radix;
            tmp[--cnt[idx]] = a[i];
        }
        copy(tmp, tmp + n, a);
    }
    delete[] tmp; delete[] cnt;
}

測試驗證

主程序對包含重複元素、大數值的測試數組 {45, 38, 26, 77, 128, 38, 25, 444, 61, 153, 9999, 1012, 43, 128} 依次應用八種算法,均正確輸出有序序列。

選擇建議

  • 小規模/近乎有序:插入排序
  • 通用高效:快速排序(隨機化版本)或歸並排序
  • 嚴格 O(n log n) 保證:堆排序或歸並排序
  • 整數/固定長度鍵值:基數排序
  • 需要穩定性:歸並排序、基數排序
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved