目录
一、选择排序
/// <summary>
/// 选择排序
/// </summary>
/// <param name="arr">需要排序的数组值</param>
/// <returns></returns>
public int[] SelectSort(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
int min = i;
for (int j = i + 1; j < n; j++)
{
if (arr[min] > arr[j]) min = j;
}
//交换
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
return arr;
}
二、插入排序
/// <summary>
/// 插入排序
/// </summary>
/// <param name="arr">需要排序的数组值</param>
/// <returns></returns>
public int[] InsertSort(int[] arr)
{
if (arr == null || arr.Length < 2)
return arr;
int n = arr.Length;
for (int i = 1; i < n; i++)
{
int temp = arr[i];
int k = i - 1;
while (k >= 0 && arr[k] > temp)
k--;
//腾出位置插进去,要插的位置是 k + 1;
for (int j = i; j > k + 1; j--)
arr[j] = arr[j - 1];
//插进去
arr[k + 1] = temp;
}
return arr;
}
三、冒泡排序
/// <summary>
/// 冒泡排序
/// </summary>
/// <param name="arr">需要排序的数组值</param>
/// <returns></returns>
public int[] BubbleSort(int[] arr)
{
if (arr == null || arr.Length < 2)
{
return arr;
}
int n = arr.Length;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arr[j + 1] < arr[j])
{
int t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
}
}
}
return arr;
}
四、希尔排序
/// <summary>
/// 希尔排序
/// </summary>
/// <param name="arr">需要排序的数组值</param>
/// <returns></returns>
public int[] ShellSort(int[] arr)
{
if (arr == null || arr.Length < 2) return arr;
int n = arr.Length;
// 对每组间隔为 h的分组进行排序,刚开始 h = n / 2;
for (int h = n / 2; h > 0; h /= 2)
{
//对各个局部分组进行插入排序
for (int i = h; i < n; i++)
{
// 将arr[i] 插入到所在分组的正确位置上
InsertIValue(arr, h, i);
}
}
return arr;
}
五、归并排序
/// <summary>
/// 归并排序(递归式)
/// </summary>
/// <param name="arr">需要排序的数组值</param>
/// <param name="left">左半部分索引</param>
/// <param name="right">右半部分索引</param>
/// <returns></returns>
public int[] MergeSort(int[] arr, int left, int right)
{
// 如果 left == right,表示数组只有一个元素,则不用递归排序
if (left < right)
{
// 把大的数组分隔成两个数组
int mid = (left + right) / 2;
// 对左半部分进行排序
arr = MergeSort(arr, left, mid);
// 对右半部分进行排序
arr = MergeSort(arr, mid + 1, right);
//进行合并
Merge(arr, left, mid, right);
}
return arr;
}
六、快速排序
/// <summary>
/// 快速排序
/// </summary>
/// <param name="arr">需要排序的数组值</param>
/// <param name="left"></param>
/// <param name="right"></param>
/// <returns></returns>
public int[] QuickSort(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>
/// <returns></returns>
public int[] HeadSort(int[] arr)
{
int n = arr.Length;
//构建大顶堆
for (int i = (n - 2) / 2; i >= 0; i--)
{
DownAdjust(arr, i, n - 1);
}
//进行堆排序
for (int i = n - 1; i >= 1; i--)
{
// 把堆顶元素与最后一个元素交换
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
// 把打乱的堆进行调整,恢复堆的特性
DownAdjust(arr, 0, i - 1);
}
return arr;
}
八、计算排序
/// <summary>
/// 计算排序
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
public int[] CountSort(int[] arr)
{
if (arr == null || arr.Length < 2) return arr;
int n = arr.Length;
int min = arr[0];
int max = arr[0];
// 寻找数组的最大值与最小值
for (int i = 1; i < n; i++)
{
if (max < arr[i])
max = arr[i];
if (min > arr[i])
min = arr[i];
}
int d = max - min + 1;
//创建大小为max的临时数组
int[] temp = new int[d];
//统计元素i出现的次数
for (int i = 0; i < n; i++)
{
temp[arr[i] - min]++;
}
int k = 0;
//把临时数组统计好的数据汇总到原数组
for (int i = 0; i < d; i++)
{
for (int j = temp[i]; j > 0; j--)
{
arr[k++] = i + min;
}
}
return arr;
}
九、桶排序
/// <summary>
/// 桶排序
/// </summary>
/// <param name="arr"></param>
/// <param name="bucketNum"></param>
public double[] BucketSort(double[] arr, int bucketNum)
{
//创建bucket时,在二维中增加一组标识位,其中bucket[x, 0]表示这一维所包含的数字的个数
double[,] bucket = new double[bucketNum, arr.Length + 1];
foreach (var num in arr)
{
int bit = (int) (bucketNum * num);
bucket[bit, (int) ++bucket[bit, 0]] = num;
}
//为桶里的每一行使用插入排序
for (int j = 0; j < bucketNum; j++)
{
//为桶里的行创建新的数组后使用插入排序
double[] insertion = new double[(int) bucket[j, 0]];
for (int k = 0; k < insertion.Length; k++)
{
insertion[k] = bucket[j, k + 1];
}
//调用插入排序
StraightInsertionSort(insertion);
//把排好序的结果回写到桶里
for (int k = 0; k < insertion.Length; k++)
{
bucket[j, k + 1] = insertion[k];
}
}
//将所有桶里的数据回写到原数组中
for (int count = 0, j = 0; j < bucketNum; j++)
{
for (int k = 1; k <= bucket[j, 0]; k++)
{
arr[count++] = bucket[j, k];
}
}
return arr;
}
十、基数排序
/// <summary>
/// 基数排序
/// </summary>
/// <param name="myArray"></param>
/// <param name="keyNum"></param>
public int[] RandixSort(int[] myArray, int keyNum)
{
SingleLinkedList<int> listArray = new SingleLinkedList<int>();
foreach (int i in myArray)
{
listArray.AddLast(new SingleLLNode<int>() {Value = i});
}
for (int i = 0; i < keyNum; i++)
{
// 对每个关键字执行分配和收集操作
DistributeAndCollect(listArray, i);
}
int j = 0;
while (listArray.First != null)
{
myArray[j++] = listArray.First.Value;
listArray.First = listArray.First.Next;
}
return myArray;
}
/// <summary>
/// 分配和收集
/// </summary>
/// <param name="listArray"></param>
/// <param name="i"></param>
private void DistributeAndCollect(SingleLinkedList<int> listArray, int i)
{
int randix = 10; //关键字取值范围
int divider = (int) Math.Pow(10, i);
List<SingleLinkedList<int>> subLists = new List<SingleLinkedList<int>>(); //建立子序列
for (int j = 0; j < randix; j++)
{
subLists.Add(new SingleLinkedList<int>());
}
// 开始一次分配
while (listArray.First != null)
{
int index = (listArray.First.Value / divider) % 10;
SingleLLNode<int> tempNode = listArray.First.Next;
subLists[index].AddLast(listArray.First);
listArray.First = tempNode;
}
// 开始一次收集
int k = 0;
for (; k < randix; k++)
{
if (subLists[k].First != null)
{
// 找到第一个非空子序列以设置总序列的First值
listArray.First = subLists[k].First;
listArray.Last = subLists[k].Last;
break;
}
}
// 找好子序列设置好listArray.First后,开始处理非空子序列的首尾相连
for (; k < randix; k++)
{
if (subLists[k].First != null)
{
listArray.Last.Next = subLists[k].First;
listArray.Last = subLists[k].Last;
}
}
}