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

C# 排序演算法實戰:委派泛型化支援任意物件與多欄位排序

     編輯:關於C#

從基本型別到領域物件

早期教學多示範 int[] 排序,實務上需對 Car、Order、User 等類別按不同欄位 (價格、名稱、日期) 排序。透過 Comparison<T> 或 IComparer<T> 即可解耦演算法與比較邏輯。

領域模型


public class Car
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public Car(string name, decimal price) { Name = name; Price = price; }
    public override string ToString() => $"{Name} : {Price:C}";
}

四大經典排序泛型實作


public static class SortAlgorithms
{
    // 冒泡排序 - 教學用,實務極少用
    public static void BubbleSort(T[] array, Comparison cmp)
    {
        for (int i = 1; i < array.Length; i++)
        {
            bool swapped = false;
            for (int j = array.Length - 1; j >= i; j--)
                if (cmp(array[j], array[j - 1]) < 0)
                { (array[j], array[j - 1]) = (array[j - 1], array[j]); swapped = true; }
            if (!swapped) break;
        }
    }

    // 快速排序 - 平均 O(n log n),不穩定
    public static void QuickSort(T[] array, Comparison cmp) => QuickSort(array, cmp, 0, array.Length - 1);
    private static void QuickSort(T[] array, Comparison cmp, int left, int right)
    {
        if (left >= right) return;
        T pivot = array[(left + right) / 2];
        int i = left - 1, j = right + 1;
        while (true)
        {
            while (cmp(array[++i], pivot) < 0) ;
            while (cmp(pivot, array[--j]) < 0) ;
            if (i >= j) break;
            (array[i], array[j]) = (array[j], array[i]);
        }
        QuickSort(array, cmp, left, i - 1);
        QuickSort(array, cmp, j + 1, right);
    }

    // 選擇排序 - O(n²),不穩定,寫入次數少 (適合寫入成本高的存儲)
    public static void SelectionSort(T[] array, Comparison cmp)
    {
        for (int i = 0; i < array.Length - 1; i++)
        {
            int min = i;
            for (int j = i + 1; j < array.Length; j++)
                if (cmp(array[j], array[min]) < 0) min = j;
            (array[i], array[min]) = (array[min], array[i]);
        }
    }

    // 插入排序 - O(n²),穩定,近乎有序資料極快 (最佳 O(n))
    public static void InsertionSort(T[] array, Comparison cmp)
    {
        for (int i = 1; i < array.Length; i++)
        {
            T key = array[i];
            int j = i;
            while (j > 0 && cmp(key, array[j - 1]) < 0)
            { array[j] = array[j - 1]; j--; }
            array[j] = key;
        }
    }
}

比較器工廠:靈活組合排序規則


public static class CarComparers
{
    public static Comparison ByPriceAsc => (a, b) => a.Price.CompareTo(b.Price);
    public static Comparison ByPriceDesc => (a, b) => b.Price.CompareTo(a.Price);
    public static Comparison ByNameAsc => (a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal);
    public static Comparison ByNameDesc => (a, b) => string.Compare(b.Name, a.Name, StringComparison.Ordinal);

    // 多鍵排序:先價格升冪,價格相同再按名稱
    public static Comparison ByPriceThenName => (a, b) =>
    {
        int r = a.Price.CompareTo(b.Price);
        return r != 0 ? r : string.Compare(a.Name, b.Name, StringComparison.Ordinal);
    };
}

使用範例


var cars = new[]
{
    new Car("Benz", 210000), new Car("BMW", 150000), new Car("VW", 130000),
    new Car("Ford", 140000), new Car("Kia", 58000), new Car("QQ", 30000),
    new Car("Fiat", 200000), new Car("Toyota", 170000), new Car("Mazda", 140000)
};

// 快速排序 + 價格升冪
SortAlgorithms.QuickSort(cars, CarComparers.ByPriceAsc);
Console.WriteLine("價格升冪:");
cars.ToList().ForEach(c => Console.WriteLine(c));

// 插入排序 + 多鍵排序
SortAlgorithms.InsertionSort(cars, CarComparers.ByPriceThenName);
Console.WriteLine("\n價格升冪、同價按名稱:");
cars.ToList().ForEach(c => Console.WriteLine(c));

實務建議:直接用內建


// List.Sort / Array.Sort / LINQ OrderBy 已高度優化 (Introsort: Quick + Heap + Insertion)
cars = cars.OrderBy(c => c.Price).ThenBy(c => c.Name).ToArray();
// 或
Array.Sort(cars, CarComparers.ByPriceThenName);
方法優點適用場景
Array.Sort / List.Sort原地排序、Introsort 保證 O(n log n)、支援 Comparison<T>一般陣列/清單排序首選
LINQ OrderBy語法宣告式、可鏈結 ThenBy、回傳新序列查詢管線、需保留原序列
自訂演算法教學、特殊限制 (外部排序、穩定性保證、寫入最小化)極少數特殊場景

總結

掌握 Comparison<T> 與 IComparer<T> 介面,即可將任何排序演算法泛型化,支援任意型別與複雜多欄位排序規則。實務開發中優先使用 .NET 內建 Array.Sort / List.Sort / LINQ OrderBy,僅在教學、面試或極特殊效能限制下手寫演算法。

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