package class01;
/**
* @author chencc
* @Description 排序算法
* @Date 2022/1/19 15:42
*/
public class Code03_Sort2 {
//TODO 1)选择排序
public static void selectSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//0-n-1 选择一个最小值,放在0位置
//1-n-1 选择一个最小值,放在1位置
//2-n-1 选择一个最小值,放在2位置
//.....
int n = arr.length;
for (int i = 0; i < n; i++) {
//假设初始最小位置为i
int minIndex = i;
//当前i,需要i+1--n-1循环比较找出最小的位置
for (int j = i + 1; j < n; j++) {
minIndex = arr[minIndex] < arr[j] ? minIndex : j;
}
//将最小值与当前i进行对换
swap(arr, minIndex, i);
}
}
//TODO 2)冒泡排序
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//冒泡排序从0开始,两两进行比较,将最大的放到最后一位
//0-n-1 选出最大的放到n-1
//0-n-2 选出最大的放到n-2
//0-n-3 选出最大的放到n-3
//.....
int end = arr.length;
//i控制最外层循环最后一个
for (int i = end - 1; i >= 0; i--) {
//边界问题,i不能<=i,不然j+1就越界
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
}
//TODO 3)插入排序
public static void insertSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//0-0 上有序
//0-1 上有序
//0-2 上有序
//...
//0-n-1 上有序
int n = arr.length;
//i从1开始,0-0只有一位数不用比,已经有序
for (int i = 1; i < n; i++) {
for (int pre = i - 1; pre >= 0 && arr[pre] > arr[pre + 1]; pre--) {
swap(arr, pre, pre + 1);
}
}
}
//TODO 4)归并排序
public static void mergeSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
//将数组一分为二
process(arr, 0, arr.length - 1);
}
public static void process(int[] arr, int L, int R) {
if (L >= R) {
return;
}
//(R+L)/2
int mid = L + ((R - L) >> 1);
//左边递归
process(arr, L, mid);
//右边递归
process(arr, mid + 1, R);
//将数组变有序
merge(arr, L, mid, R);
}
public static void merge(int[] arr, int L, int M, int R) {
//创建一个等大小的空数组
int[] help = new int[R - L + 1];
//初始指针
int i = 0;
int p1 = L;
int p2 = M + 1;
while (p1 <= M && p2 <= R) {
//数组左边有序部分,跟数组右边有序部分,进行比较,将较小的值放入help数组,然后自己的坐标+1,help坐标也+1
//直到有一侧越界为止,及p1>M或者p2>R,跳出循环
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
//此时存在有一侧还没有遍历完
while (p1 <= M) {
help[i++] = arr[p1++];
}
while (p2 <= R) {
help[i++] = arr[p2++];
}
//将help值重新覆盖arr数组
for (int j = 0; j < help.length; j++) {
arr[L + j] = help[j];
}
}
//TODO 5)快排
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickProcess(arr, 0, arr.length - 1);
}
public static void quickProcess(int[] arr, int L, int R) {
if (L >= R) {
return;
}
//获取等于区域的坐标
int[] equalE = partition(arr, L, R);
//数组等于p左边部分递归
quickProcess(arr, L, equalE[0] - 1);
//数组等于p右边部分递归
quickProcess(arr, equalE[1] + 1, R);
}
//当前数<p,当前数与<区下一位交换,<区右扩,当前数跳下一位
//当前数=p,当前数跳下一位
//当前数>p,当前数与>区前一位交换,>区左扩,指针不变
public static int[] partition(int[] arr, int L, int R) {
int lessLeft = L - 1;
int moreRight = R;
int index = L;
while (index < moreRight) {
if (arr[index] < arr[R]) {
swap(arr, ++lessLeft, index++);
} else if (arr[index] > arr[R]) {
swap(arr, --moreRight, index);
} else {
index++;
}
}
//所有的数遍历比较完成,将p值与当前>区位置数进行对换
swap(arr, moreRight, R);
return new int[]{lessLeft + 1, moreRight};
}
//对换
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//打印数组
private static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] a = {9, 3, 5, 7, 1, 0, 4, 6, 3, 8, 3, 7, 4};
printArray(a);
quickSort(a);
printArray(a);
}
}
排序算法汇总
于 2022-01-21 16:02:52 首次发布