前文實現了針對一維整數陣列的四種排序,但實務專案需對任意物件、依任意條件排序(如航班按時間、商品按價格)。本文改良程式碼,引入委派策略模式,實現通用排序框架。
namespace Sorter
{
// 比較策略委派
public delegate bool CompareOperation(object objPrev, object objNext);
// 領域物件:汽車
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:{Name}, price:{Price:c}";
// 策略實作:按名稱/價格比較
public static bool OrderByCarName(object a, object b)
=> ((Car)a).Name.CompareTo(((Car)b).Name) < 0;
public static bool OrderByCarPrice(object a, object b)
=> ((Car)a).Price < ((Car)b).Price;
}
// 冒泡排序
public class BubbleSorter
{
public static void Sort(object[] arr, CompareOperation op)
{
bool flag;
for (int i = 1; i < arr.Length; i++)
{
flag = false;
for (int j = arr.Length - 1; j >= i; j--)
if (op(arr[j], arr[j - 1]))
{
var tmp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = tmp;
flag = true;
}
if (!flag) return;
}
}
}
// 快速排序
public class QuickSort
{
public static void Sort(object[] arr, CompareOperation op)
=> Sort(arr, op, 0, arr.Length - 1);
private static void Sort(object[] arr, CompareOperation op, int left, int right)
{
if (left >= right) return;
object mid = arr[(left + right) / 2];
int i = left - 1, j = right + 1;
while (true)
{
while (op(arr[++i], mid)) ;
while (op(mid, arr[--j])) ;
if (i >= j) break;
Swap(arr, i, j);
}
Sort(arr, op, left, i - 1);
Sort(arr, op, j + 1, right);
}
private static void Swap(object[] arr, int i, int j)
{
var t = arr[i]; arr[i] = arr[j]; arr[j] = t;
}
}
// 選擇排序
public class SelectionSort
{
public static void Sort(object[] arr, CompareOperation op)
{
for (int i = 0; i < arr.Length - 1; i++)
{
int min = i;
for (int j = i + 1; j < arr.Length; j++)
if (op(arr[j], arr[min])) min = j;
var t = arr[i]; arr[i] = arr[min]; arr[min] = t;
}
}
}
// 插入排序
public class InsertSort
{
public static void Sort(object[] arr, CompareOperation op)
{
for (int i = 1; i < arr.Length; i++)
{
object t = arr[i];
int j = i;
while (j > 0 && op(t, arr[j - 1]))
{
arr[j] = arr[j - 1];
j--;
}
arr[j] = t;
}
}
}
}
OrderByCarName, OrderByCarPrice) 封裝領域比較規則。