先来看随机生成9999个数据时,普通桶装排序与向量伪桶装+快排序的效率对比
再来看随机生成9999个数据时,快排序与向量伪桶装+快排序的效率对比
不罗嗦直接上代码
public static class VectorHelper
{
/// <summary>
/// 向量分块
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="src">数据源</param>
/// <param name="cntRem">剩余数量</param>
/// <returns></returns>
public static Vector<T>[] VectorBlock<T>(this T[] src,out int cntBlock, out int cntRem) where T : struct
{
int count=src.Length;
// Block width.
int vectorWidth = src[0].VectorWidth<T>();
// Block count.
cntBlock = count / vectorWidth;
// Remainder count.
cntRem = count % vectorWidth;
// Index for src data.
int p =0,i;
// Load.
// Vector src
Vector<T>[] vsrc = new Vector<T>[cntBlock+1];
for (i = 0; i < vsrc.Length-1; i++)
{
vsrc[i] = new Vector<T>(src, p);
p += vectorWidth;
}
// Remainder processs.
if (cntRem != 0)
{
T[] tempArr= new T[vectorWidth];
int j;
for (j = 0;j< cntRem; j++)
{
tempArr[j]= src[p++];
}
// 注:末尾不够时,值为default(T),不如int类型时默认为0,自行去除
vsrc[i] = new Vector<T>(tempArr,0);
}
return vsrc;
}
/// <summary>
/// Block width.
/// </summary>
public static int VectorWidth<T>(this T t) where T : struct => Vector<T>.Count;
/// <summary>
/// 对向量内元素排序
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="vector"></param>
/// <returns></returns>
public static Vector<int> VectorSort(this Vector<int> vector)
{
// Block width.
int vectorWidth = Vector<int>.Count;
int[] data = new int[vectorWidth];
for (int i = 0; i < vectorWidth; i++)
{
data[i] = vector[i];
}
data.QuickSort(0, vectorWidth-1);
return new Vector<int>(data);
}
#region 快速排序
/// <summary>
/// 快速排序
/// </summary>
/// <param name="arr">需要排序的数组值</param>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public static int[] QuickSort(this int[] arr, int left, int right)
{
if (left < right)
{
//获取中轴元素所处的位置
int mid = PartPosition(arr, left, right);
//进行分割
arr = QuickSort(arr, left, mid - 1);
arr = QuickSort(arr, mid + 1, right);
}
return arr;
}
/// <summary>
/// 获取中轴元素所处的位置
/// </summary>
/// <param name="arr"></param>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
private static int PartPosition(int[] arr, int left, int right)
{
//选取中轴元素
int pivot = arr[left];
int i = left + 1;
int j = right;
while (true)
{
// 向右找到第一个小于等于 pivot 的元素位置
while (i <= j && arr[i] <= pivot) i++;
// 向左找到第一个大于等于 pivot 的元素位置
while (i <= j && arr[j] >= pivot) j--;
if (i >= j)
break;
//交换两个元素的位置,使得左边的元素不大于pivot,右边的不小于pivot
arr.Swap(i,j);
}
arr[left] = arr[j];
// 使中轴元素处于有序的位置
arr[j] = pivot;
return j;
}
/// <summary>
/// 交换元素
/// </summary>
/// <param name="arr"></param>
/// <param name="i"></param>
/// <param name="j"></param>
public static void Swap(this int[] arr,int i,int j)
{
//arr[i] = arr[i] ^ arr[j];
//arr[j] = arr[i] ^ arr[j];
//arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^= arr[j] ^= arr[i] ^= arr[j] ^= arr[i];
}
#endregion
}
调用:
static void Main(string[] args)
{
int num = 9999 ;
Console.WriteLine($"数组大小:{num}");
Random random = new Random();
int[] src = new int[num];
for (int i = 0; i < num; i++)
{
src[i] = random.Next(0, num);
}
Stopwatch sw = new Stopwatch();
sw.Start();
// 尾数有0,为0的个数为cntBlock-cntRem
Vector<int>[] data = src.VectorBlock(out int cntBlock, out int cntRem);
for (int i = 0; i < cntBlock; i++)
{
var temp= data[i].VectorSort();
data[i] = temp;
}
sw.Stop();
Console.WriteLine($"向量桶装排序用时:{sw.ElapsedMilliseconds}ms");
sw.Restart();
//bucketSort(src, num, Vector<int>.Count);
src.QuickSort(0, src.Length - 1);
sw.Stop();
Console.WriteLine($"普通快排序用时:{sw.ElapsedMilliseconds}ms");
}
注:普通桶装源码 C# 实现桶排序_游子吟i的博客-优快云博客_c# 桶排序