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

C# 四大經典排序演算法實作與效能實測:氣泡、插入、選擇、快速排序

     編輯:關於C#

演算法複雜度理論比較

演算法平均時間最壞時間空間穩定性備註
氣泡排序O(n²)O(n²)O(1)穩定教學用,實務極少用
插入排序O(n²)O(n²)O(1)穩定小資料/近乎有序時極快
選擇排序O(n²)O(n²)O(1)不穩定交換次數最少 O(n)
快速排序O(n log n)O(n²)O(log n)不穩定實務首選,.NET 內建即採用

C# 完整實作程式碼


using System;

public interface ISortAlgorithm
{
    void Sort(int[] array);
    string Name { get; }
}

// 1. 氣泡排序
public class BubbleSort : ISortAlgorithm
{
    public string Name => "Bubble Sort";
    public void Sort(int[] arr)
    {
        int n = arr.Length;
        for (int i = 0; i < n - 1; i++)
        {
            bool swapped = false;
            for (int j = 0; j < n - 1 - i; j++)
            {
                if (arr[j] > arr[j + 1])
                {
                    (arr[j], arr[j + 1]) = (arr[j + 1], arr[j]); // C# 7 元組交換
                    swapped = true;
                }
            }
            if (!swapped) break; // 優化:提前結束
        }
    }
}

// 2. 插入排序
public class InsertionSort : ISortAlgorithm
{
    public string Name => "Insertion Sort";
    public void Sort(int[] arr)
    {
        for (int i = 1; i < arr.Length; i++)
        {
            int key = arr[i];
            int j = i - 1;
            while (j >= 0 && arr[j] > key)
            {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = key;
        }
    }
}

// 3. 選擇排序
public class SelectionSort : ISortAlgorithm
{
    public string Name => "Selection Sort";
    public void Sort(int[] arr)
    {
        for (int i = 0; i < arr.Length - 1; i++)
        {
            int minIdx = i;
            for (int j = i + 1; j < arr.Length; j++)
                if (arr[j] < arr[minIdx]) minIdx = j;
            
            if (minIdx != i)
                (arr[i], arr[minIdx]) = (arr[minIdx], arr[i]);
        }
    }
}

// 4. 快速排序 (原地分區)
public class QuickSort : ISortAlgorithm
{
    public string Name => "Quick Sort";
    public void Sort(int[] arr) => QuickSortInternal(arr, 0, arr.Length - 1);

    private void QuickSortInternal(int[] arr, int low, int high)
    {
        if (low >= high) return;

        int pivot = arr[low]; // 簡單選擇首元素為基準
        int i = low, j = high;

        while (i < j)
        {
            while (i < j && arr[j] >= pivot) j--;
            if (i < j) arr[i++] = arr[j];

            while (i < j && arr[i] <= pivot) i++;
            if (i < j) arr[j--] = arr[i];
        }
        arr[i] = pivot;

        QuickSortInternal(arr, low, i - 1);
        QuickSortInternal(arr, i + 1, high);
    }
}

效能測試框架


public static class SortBenchmark
{
    public static void Run(int arraySize = 100_000, int testRounds = 5)
    {
        var algorithms = new ISortAlgorithm[]
        {
            new BubbleSort(),
            new InsertionSort(),
            new SelectionSort(),
            new QuickSort(),
            new SystemSort() // 對照組:Array.Sort
        };

        Console.WriteLine($"陣列大小:{arraySize:N0},測試輪數:{testRounds}");
        Console.WriteLine(new string('=', 60));

        foreach (var algo in algorithms)
        {
            long totalMs = 0;
            for (int round = 0; round < testRounds; round++)
            {
                int[] data = GenerateRandomArray(arraySize);
                int[] copy = (int[])data.Clone();

                var sw = System.Diagnostics.Stopwatch.StartNew();
                algo.Sort(copy);
                sw.Stop();

                totalMs += sw.ElapsedMilliseconds;
                
                // 驗證正確性 (僅第一輪)
                if (round == 0 && !IsSorted(copy))
                    Console.WriteLine($"  ⚠️ {algo.Name} 排序結果錯誤!");
            }
            Console.WriteLine($"{algo.Name,-15} 平均耗時:{totalMs / (double)testRounds,8:F1} ms");
        }
    }

    private static int[] GenerateRandomArray(int size)
    {
        var rnd = new Random(42); // 固定種子確保公平
        var arr = new int[size];
        for (int i = 0; i < size; i++) arr[i] = rnd.Next(int.MinValue, int.MaxValue);
        return arr;
    }

    private static bool IsSorted(int[] arr)
    {
        for (int i = 1; i < arr.Length; i++)
            if (arr[i - 1] > arr[i]) return false;
        return true;
    }
}

// 對照組:.NET 內建排序 (Introsort:快速+堆積+插入混合)
public class SystemSort : ISortAlgorithm
{
    public string Name => "Array.Sort";
    public void Sort(int[] arr) => Array.Sort(arr);
}

實測結果範例 (100,000 筆隨機整數,5 輪平均)

============================================================
Bubble Sort       平均耗時:  12,450.2 ms  (約 12.5 秒)
Insertion Sort    平均耗時:   3,210.5 ms  (約 3.2 秒)
Selection Sort    平均耗時:   1,850.3 ms  (約 1.9 秒)
Quick Sort        平均耗時:        12.3 ms  (0.012 秒)
Array.Sort        平均耗時:         8.7 ms  (最快)
============================================================

深度分析與避坑指南

  1. 氣泡排序最慢:雙層迴圈 + 大量交換,教學價值大於實務。
  2. 插入排序次之:資料近乎有序時接近 O(n),適合小陣列 (通常 < 50)。
  3. 選擇排序優於氣泡:交換次數固定 O(n),但比較次數仍 O(n²)。
  4. 快速排序碾壓:分治法 O(n log n),但最壞情況 (已排序陣列 + 首元素基準) 退化 O(n²)。
    → 實務建議:隨機選基準或三數取中法。
  5. Array.Sort 最強:.NET 使用 Introsort (Quick + Heap + Insertion 混合),自動切換策略,無最壞情況退化。

現代 C# 實務建議


// 99% 情況直接用內建
Array.Sort(array);                    // 陣列原地排序
list.Sort();                          // List 原地排序
var sorted = array.OrderBy(x => x);   // LINQ 產生新序列 (穩定排序)

// 自訂比較
Array.Sort(array, (a, b) => b.CompareTo(a)); // 降序
Array.Sort(array, Comparer.Create((a,b) => a - b));
只有在教學、面試、極度受限環境 (無標準庫) 或需要特定穩定性/空間限制時,才手寫排序演算法。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved