C#排序算法——快速排序法

来源:互联网 发布:我的网络研修计划 编辑:程序博客网 时间:2024/06/06 18:38

  在阅读此博文前,请先阅读我的博文“C#排序算法——基类设计“,以了解基类的结构。
  在编写代码前,我们先来了解二路归并法的排序过程:
  假设有一个IList<T>型的集合list(集合的元素为list[0]到list[n-1], n = list.Count)。
  第1步:从a[0 : n - 1]中选择一个元素作为middle,该元素为支点。
  第2步:把余下的元素分割为两段left和right,使得left中的元素都小于等于支点,而right中的元素都大于等于支点。
  第3步,递归地使用快速排序方法对left 进行排序。
  
第4步,递归地使用快速排序方法对right 进行排序。
  很显然,快速排序法同样使用了递归调用。根据上面的算法,我们开始编码了:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;

  4. namespace CYB.DataStruct.Sorting
  5. {
  6.     /// <summary>
  7.     /// 作者 : cyb
  8.     /// 发表时间 : 2008-9-13
  9.     /// qq : 13101908
  10.     /// e-mail : hustcyb@gmail.com
  11.     /// </summary>
  12.     public class QuickSorter : Sorter
  13.     {
  14.         public override void Sort<T>(IList<T> list, CompareDelegate<T> compare)
  15.         {
  16.             base.Sort(list, compare);

  17.             QuickSort(list, 0, list.Count - 1, compare);
  18.         }


  19.         /// <param name="left">子集的起始索引号</param>
  20.         /// <param name="right">子集的终止索引号</param>
  21.         private void QuickSort<T>(IList<T> list, int left, int right, CompareDelegate<T> compare)
  22.         {
  23.             if (left >= right)
  24.             {
  25.                 return;             //子集元素个数小于1,直接返回
  26.             }

  27.             int l = left + 1;       //从左往右扫描的游标
  28.             int r = right;          //从右往左扫描的游标
  29.             T pivot = list[left];   //选择最左端元素作为支点

  30.             while (true)
  31.             {
  32.                 //从左往右扫描找出所有小于支点的元素
  33.                 while (l < right && compare(list[l], pivot) <= 0)
  34.                 {
  35.                     ++l;
  36.                 }

  37.                 //从右往左扫描找出所有大于支占的元素
  38.                 while (compare(list[r], pivot) > 0)
  39.                 {
  40.                     --r;
  41.                 }

  42.                 if (l >= r)
  43.                 {
  44.                     break;
  45.                 }
  46.                 else
  47.                 {
  48.                     SwapListItem(list, l, r); //交换左右游标的元素
  49.                 }
  50.             }

  51.             //将支点移到中间
  52.             list[left] = list[r];
  53.             list[r] = pivot;

  54.             //递归地使用快速排序法对由支点作为边界的左右子集进行排序
  55.             QuickSort(list, left, r - 1, compare);
  56.             QuickSort(list, r + 1, right, compare);
  57.         }
  58.     }
  59. }


原创粉丝点击