1、冒泡排序
//冒泡排序 O(n²)
class BubbleSort
{
public static void Sort(int[] arr)
{
int n = arr.Length;
//外层循环控制冒泡次数
for (int i = 0; i < n; i++)
{
//减去i 不需要对已经排好序的元素再次进行比较
//内层循环在数组[0...n-1-i]范围内冒泡最大值
//j取值范围[0...n-1-i) j+1取值范围[1...n-1-i]
for (int j = 0; j < n - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
Swap(arr, j, j + 1);
}
}
}
//交换数组中索引i和j对应元素的位置
private static void Swap(int[] arr,int i,int j)
{
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
2、冒泡排序-泛型
class BubbleSortGeneric
{
public static void Sort<E>(E[] arr) where E:IComparable<E>
{
int n = arr.Length;
//外层循环控制冒泡次数
for (int i = 0; i < n; i++)
{
//减去i 不需要对已经排好序的元素再次进行比较
for (int j = 0; j < n - 1 - i; j++)
{
if (arr[j].CompareTo(arr[j + 1])>0)
Swap(arr, j, j + 1);
}
}
}
private static void Swap<E>(E[] arr, int i, int j)
{
E t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
3、选择排序
class SelectSort
{
public static void Sort(int[] arr)
{
int n = arr.Length;
//外层循环控制每一轮循环中要交换的位置i
//第一轮循环 i=0 执行循环体内逻辑 找到最小值然后和arr[i]交换 将第一个元素排好序
//第二轮循环 i=1 执行循环体内逻辑 找到最小值然后和arr[i]交换 将第二个元素排好序
//....
//第n轮循环 i=n-1 执行循环体内逻辑 找到最小值然后和arr[i]交换 将最后一个元素排好序
//跳出外层循环 完成整个数组的选择排序
for (int i = 0; i < n; i++)
{
//最小元素的索引min 从未排序的第一个位置i开始寻找
int min = i;
//内层循环在[i+1...n)寻找最小值对应的索引min
for (int j = i+1; j < n; j++)
{
if (arr[j] < arr[min])
min = j;
}
//内层循环结束,找到最小值arr[min],和未排序的边界元素arr[i]交换位置
Swap(arr, i, min);
}
}
private static void Swap(int[] arr,int i,int j)
{
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
4、插入排序
class InsertSort
{
public int [] InSort(int [] arr)
{
int n = arr.Length;
for (int i = 1; i < n; i++)
{
int e = arr[i];
int j;//位置
for ( j = i; j >0; j--)
{
if (e < arr[j - 1])
{
arr[j] = arr[j - 1];
}
else
break;
}
arr[j] = e;
}
return arr;
}
//对arr[l...r]的范围使用插入排序
public static void Sort1(int[] arr,int l,int r)
{
for (int i = l+1; i <= r; i++)
{
int e = arr[i];
int j;
for (j = i; j > l; j--)
{
if (e < arr[j - 1])
arr[j] = arr[j - 1];
else
break;
}
arr[j] = e;
}
}
}
5、归并排序
//时间复杂度O(nlogn)
//空间复杂度O(n)需要借助一个同样长度的辅助数组进行排序
class MergeSort1
{
//用户调用的排序方法传进数组即可排序
public static void Sort(int[] arr)
{
int n = arr.Length;
int[] temp = new int[n];
Sort(arr, temp, 0, n - 1);
}
//递归使用归并排序,对arr[l...r]的范围进行排序
private static void Sort(int[] arr,int[] temp,int l,int r)
{
if (l >= r) return;//可以在这里进行优化,看下面的Sort2
//int mid = (r + l) / 2;
int mid = l + (r - l) / 2;
//Console.WriteLine("mid = {0}", mid);
Sort(arr, temp, l, mid); //将左半边排序
Sort(arr, temp, mid + 1, r); //将右半边排序
Merge(arr, temp, l, mid, r); //归并结果
}
// 将arr[l...mid]和arr[mid+1...r]两部分有序排列进行归并
private static void Merge(int[] arr,int[] temp,int l,int mid ,int r)
{
//Console.WriteLine("Merge({0},{1},{2})", l, mid, r);
int i = l;
int j = mid + 1;
int k = l;
//左右半边都有元素(将小的放到temp数组中)
while(i<=mid && j <= r)
{
if(arr[i] < arr[j])
temp[k++] = arr[i++];
else //arr[i] >= arr[j]
temp[k++] = arr[j++];
}
//左半边还有元素,右半边用尽(取左半边的元素)
while (i <= mid)
temp[k++] = arr[i++];
//右半边还有元素,左半边用尽(取右半边的元素)
while (j <= r)
temp[k++] = arr[j++];
//将temp数组拷贝回给arr数组,完成arr排序
for (int z = l; z <= r; z++)
arr[z] = temp[z];
}
}
6、归并排序(优化),在递归终止条件处处理,数组长度小时使用插入排序即可
//时间复杂度O(nlogn)
//空间复杂度O(n)需要借助一个同样长度的辅助数组进行排序
class MergeSort2
{
//用户调用的排序方法传进数组即可排序
public static void Sort(int[] arr)
{
int n = arr.Length;
int[] temp = new int[n];
Sort(arr, temp, 0, n - 1);
}
//递归使用归并排序,对arr[l...r]的范围进行排序
private static void Sort(int[] arr, int[] temp, int l, int r)
{
if (r - l + 1 <= 15)
{
InsertSort.Sort1(arr, l, r);
return;
}
int mid = l + (r - l) / 2;
Sort(arr, temp, l, mid); //将左半边排序
Sort(arr, temp, mid + 1, r); //将右半边排序
if (arr[mid] > arr[mid + 1])
Merge(arr, temp, l, mid, r); //归并结果
}
// 将arr[l...mid]和arr[mid+1...r]两部分有序排列进行归并
private static void Merge(int[] arr, int[] temp, int l, int mid, int r)
{
int i = l;
int j = mid + 1;
int k = l;
//左右半边都有元素(将小的放到temp数组中)
while (i <= mid && j <= r)
{
if (arr[i] < arr[j])
temp[k++] = arr[i++];
else //arr[i] >= arr[j]
temp[k++] = arr[j++];
}
//左半边还有元素,右半边用尽(取左半边的元素)
while (i <= mid)
temp[k++] = arr[i++];
//右半边还有元素,左半边用尽(取右半边的元素)
while (j <= r)
temp[k++] = arr[j++];
//将temp数组拷贝回给arr数组,完成arr排序
for (int z = l; z <= r; z++)
arr[z] = temp[z];
}
}
7、快速排序
//快速排序 O(nlogn)
class QuickSort1
{
public static void Sort(int[] arr)
{
int n = arr.Length;
Sort(arr, 0, n - 1);
}
private static void Sort(int[] arr,int l,int r)
{
if (r - l + 1 <= 15)
{
InsertSort.Sort1(arr, l, r);
return;
}
int v = arr[l];
int j = l; // arr[l+1...j] < v arr[j+1...i-1] > v
for (int i = l+1; i <= r; i++)
{
if(arr[i] < v)
{
j++;
Swap(arr, i, j);
}
}
Swap(arr, l, j);
Sort(arr, l, j - 1);
Sort(arr, j + 1, r);
}
private static void Swap(int[] arr,int i,int j)
{
int e = arr[i];
arr[i] = arr[j];
arr[j] = e;
}
}
8、快速排序(优化),在递归终止条件处处理,数组长度小时使用插入排序即可
class QuickSort2
{
private static Random rd = new Random();
public static void Sort(int[] arr)
{
int n = arr.Length;
Sort(arr, 0, n - 1);
}
private static void Sort(int[] arr, int l, int r)
{
if (r - l + 1 <= 15)
{
InsertSort.Sort1(arr, l, r);
return;
}
int p =l + rd.Next(r - l + 1);
Swap(arr, l, p);
int v = arr[l];
int j = l; // arr[l+1...j] < v arr[j+1...i-1] > v
for (int i = l + 1; i <= r; i++)
{
if (arr[i] < v)
{
j++;
Swap(arr, i, j);
}
}
Swap(arr, l, j);
Sort(arr, l, j - 1);
Sort(arr, j + 1, r);
}
private static void Swap(int[] arr, int i, int j)
{
int e = arr[i];
arr[i] = arr[j];
arr[j] = e;
}
}
9、快速排序(优化), 对标定元素随机化处理,对排序有序性很强的数组会得到很大的优化
class QuickSort3
{
private static Random rd = new Random();
public static void Sort(int[] arr)
{
int n = arr.Length;
Sort(arr, 0, n - 1);
}
private static void Sort(int[] arr,int l ,int r)
{
//对小规模的数组使用插入排序,避免频繁的递归调用
if (r - l + 1 <= 15)
{
InsertSort.Sort1(arr, l, r);
return;
}
//随机化处理,对排序有序性很强的数组会得到很大的优化
int p = l + rd.Next(r - l + 1);
Swap(arr, l, p);
int v = arr[l]; //标定元素v
int lt = l; // arr[l+1...lt] < v
int gt = r + 1; // arr[gt...r] > v
int i = l + 1; // arr[lt+1...i-1] == v
//往三个区间填充元素
while(i < gt)
{
if(arr[i] < v)
{
lt++;
Swap(arr, i, lt);
i++;
}
else if(arr[i] > v)
{
gt--;
Swap(arr, i, gt);
}
else //arr[i]==v
{
i++;
}
}
//跳出while循环填充完毕后,把标定元素放到合适位置
Swap(arr, l, lt);
Sort(arr, l, lt - 1); //将左半部分arr[l...lt-1]排序
Sort(arr, gt, r); //将右半部分arr[gt...r]排序
}
private static void Swap(int[] arr,int i,int j)
{
int e = arr[i];
arr[i] = arr[j];
arr[j] = e;
}
}