C#中利用委托实现通用快速排序算法
在C#编程中,实现一个既能处理整数又能处理其他类型数据的快速排序,通常需要依赖泛型或接口。本文展示了一种基于delegate的经典方法:通过将“元素比较”这一行为抽象为独立的委托对象传入排序过程。这种方法虽然不如现代List<T>.Sort()便捷,但它是理解C#回调机制与算法设计结合的优秀范例。
快速排序的核心逻辑
快速排序(Quick Sort)是一种高效的交换排序算法。其核心思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
C#中的委托实现方案
为了让排序算法不依赖于具体的数据类型(如仅针对int),我们可以在类内部定义一个委托。在调用递归排序前,创建一个实现了具体比较逻辑的委托实例并传给排序函数。
class QuickSort {
// 定义用于比较大小的委托
private delegate int CmpOp(object Left, object Right);
// 执行数组元素交换,确保代码复用
private void swap(object[] Array, int Left, int Right, CmpOp Cmp) {
object tempObj = Array[Left];
Array[Left] = Array[Right];
Array[Right] = tempObj;
}
// 定义实际执行比较的逻辑(以整数为例)
private int CmpInt(object Left, object Right) {
if ((int) Left < (int) Right)
return -1;
else
return -2;
}
public QuickSort(object[] Array) {
// 实例化具体的比较方法,绑定到委托上
CmpOp Cmp = new CmpOp(CmpInt);
Sort(Array, 0, Array.Length-1, Cmp);
}
private void Sort(object[] Array, int Left, int Right, CmpOp Cmp) {
int LHold = Left;
int RHold = Right;
// 随机选择基准点以避免最坏情况
Random ObjRan = new Random();
int Pivot = ObjRan.Next(Left,Right);
swap(Array, Pivot, Left, Cmp);
Pivot = Left;
Left++;
while (Right >= Left) {
// 根据传入的委托判断左右指针元素的相对大小
if (Cmp(Array[Left], Array[Pivot])!= -1
&& Cmp(Array[Right], ArrObj[Pivot])== -1)
swap(Array, Left, Right, Cmp);
else if (Cmp(Array[Left], Array[Pivot]) != -1)
Right--;
else if (Cmp(Array[Right],Array[Pivot]) == -1)
Left++;
else {
Right--;
Left++;
}
}
swap(Array, Pivot, Right, Cmp);
Pivot = Right;
if (Pivot > LHold)
Sort(Array, LHold, Pivot, Cmp);
if (RHold > Pivot+1)
Sort(Array, Pivot+1,RHold, Cmp);
}
}
关键参数与步骤解析
- 定义比较策略:通过
private delegate int CmpOp(object Left, object Right),我们将比较的逻辑剥离出来。
目的:解耦算法与具体的数据类型。 - 构造器初始化:在创建
QuickSort实例时,传入待排序数组。我们在内部实例化一个委托变量Cmp并赋值给刚才定义的CmpInt方法。
入口:new QuickSort(Array)。 动作:生成对应的比较实例,并触发第一层递归调用。 - 枢轴(Pivot)选取:代码中使用
Random.Next随机选择一个下标作为枢轴。
优势:相比于总是选第一个元素,这可以有效防止输入数据本身就是逆序时算法退化至O(N²)的最差时间复杂度。
完成状态的判断
当所有递归分支执行完毕后,Array内部的元素将依据CmpInt中预设的规则(即数值从小到大)被完全排列。您可以输出数组验证其顺序是否满足预期。
局限性与现代改进建议
原文代码使用的是非泛型的object[]数组,这在现代C#开发中存在两个主要问题:
- 性能损耗:频繁使用
object导致装箱(Boxing)和拆箱(Unboxing)开销,极大影响性能。 - 泛型替代:现在通常建议使用
List<T>并结合IComparer<T>接口来实现,或者直接使用内置的Array.Sort方法提供自定义比较器。
以上就是C#利用委托实现快速排序的详细代码实例与技术分析,更多关于C#算法优化的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









