C#中利用委托实现通用快速排序算法

纸上星河
纸上星河
发布时间:2026-10-13 | 5人浏览过
原创

在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#开发中存在两个主要问题:

  1. 性能损耗:频繁使用object导致装箱(Boxing)和拆箱(Unboxing)开销,极大影响性能。
  2. 泛型替代:现在通常建议使用List<T>并结合IComparer<T>接口来实现,或者直接使用内置的Array.Sort方法提供自定义比较器。

以上就是C#利用委托实现快速排序的详细代码实例与技术分析,更多关于C#算法优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表