在阅读此博文前,请先阅读我的博文“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 进行排序。
很显然,快速排序法同样使用了递归调用。根据上面的算法,我们开始编码了:
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace CYB.DataStruct.Sorting
- {
- /// <summary>
- /// 作者 : cyb
- /// 发表时间 : 2008-9-13
- /// qq : 13101908
- /// e-mail : hustcyb@gmail.com
- /// </summary>
- public class QuickSorter : Sorter
- {
- public override void Sort<T>(IList<T> list, CompareDelegate<T> compare)
- {
- base .Sort(list, compare);
- QuickSort(list, 0, list.Count - 1, compare);
- }
- /// <param name="left">子集的起始索引号</param>
- /// <param name="right">子集的终止索引号</param>
- private void QuickSort<T>(IList<T> list, int left, int right, CompareDelegate<T> compare)
- {
- if (left >= right)
- {
- return ; //子集元素个数小于1,直接返回
- }
- int l = left + 1; //从左往右扫描的游标
- int r = right; //从右往左扫描的游标
- T pivot = list[left]; //选择最左端元素作为支点
- while ( true )
- {
- //从左往右扫描找出所有小于支点的元素
- while (l < right && compare(list[l], pivot) <= 0)
- {
- ++l;
- }
- //从右往左扫描找出所有大于支占的元素
- while (compare(list[r], pivot) > 0)
- {
- --r;
- }
- if (l >= r)
- {
- break ;
- }
- else
- {
- SwapListItem(list, l, r); //交换左右游标的元素
- }
- }
- //将支点移到中间
- list[left] = list[r];
- list[r] = pivot;
- //递归地使用快速排序法对由支点作为边界的左右子集进行排序
- QuickSort(list, left, r - 1, compare);
- QuickSort(list, r + 1, right, compare);
- }
- }
- }