基础是快速排序法,但是单独写快速排序法太没创意,于是我用多线程来加快排序速度.
昨天和同学讨论快速排序时突然脑抽想到这个,没有专门去学习并行算法,所以是否合理就不晓得了..= =|||
对于CPU核心很多的机器来说,应该能起到加速的作用,但用在个人电脑上纯属没事找事,浪费资源..= =|||
using
System;
using
System.Threading;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace
Takamachi660.Math
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
public static class MultiThreadQuickSort_V4<T> where T : IComparable<T> //泛型约束:泛型参数必须实现IComparable接口
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
private class Package //封装参数,因为Thread.Start()方法仅允许一个object类型的参数
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
public T[] a; //数组对象
public int left; //左指针(索引)
public int right; //右指针(索引)
public Package(T[] a, int left, int right)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
this.a = a;
this.left = left;
this.right = right;
}
}
private delegate void SortDelegate(object pkg);
private delegate int PartDelegate(T[] a, int index, T m, int boun, bool IsLeft); //声明两个委托类型
static public IAsyncResult BeginInvokeQuickSort(T[] Objs, AsyncCallback SortFinished, object CallBackParameter) //对外接口,异步调用,返回一个指示异步执行状态的IAsyncResult对象
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{//三个参数分别为:要排序的数组,排序完成后的回调函数委托,回调函数的参数
return new SortDelegate(Sorting).BeginInvoke(new Package(Objs, 0, Objs.Length - 1), SortFinished, CallBackParameter);
}
static private void Sorting(object pkg) //快速排序递归函数
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{ //拆箱子
T[] a = ((Package)pkg).a;
int left = ((Package)pkg).left;
int right = ((Package)pkg).right;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (left >= right) //递归结束条件
return;
int l, r;
T m; //中间元素的值
l = left - 1;
r = right + 1;
m = a[left];//以第一个元素作为中间元素
while (l < r)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{ //通过异步调用使左右指针同时移动
PartDelegate par = new PartDelegate(Position);
IAsyncResult arl = par.BeginInvoke(a, l, m, right, true, null, null);
r = Position(a, r, m, left, false);
l = par.EndInvoke(arl);
if ((l + 1) < (r - 1))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
T iTemp = a[l + 1];
a[l + 1] = a[r - 1];
a[r - 1] = iTemp;
}
else
break;
}
if (l > r)
l = r;
a[left] = a[l];
a[l] = m;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Thread leftpart = new Thread(new ParameterizedThreadStart(Sorting));
leftpart.IsBackground = true; //后台线程
leftpart.Priority = ThreadPriority.BelowNormal; //优先级低于正常
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
leftpart.Start(new Package(a, left, l - 1)); //递归调用,左边部分和右边部分同时开始排序,启动一条新线程排序左边部分
Sorting(new Package(a, l + 1, right)); //当前线程排序右边部分
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
leftpart.Join(); //等待左边部分完成
}
static private int Position(T[] a, int index, T m, int boun, bool IsLeft)
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
while (IsLeft ? (index < boun && (a[index + 1] as IComparable<T>).CompareTo(m) <= 0) : (index > boun && (a[index - 1] as IComparable<T>).CompareTo(m) > 0))
![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (IsLeft)
index++;
else
index--;
}
return index;
}
}
}