
package com.at.sort;
import java.util.Arrays;
/**
* @author shkstart
* @creat ${2020}-${10}-${22}${14:54}
*/
//快排
public class QuickSort {
public static void main(String[] args) {
int[] arr = {-9, 78, 0,0,-9,0 ,23, -567, 70};
quickSort(arr, 0, arr.length - 1);
System.out.println("arr=" + Arrays.toString(arr));
}
public static void quickSort(int[] arr, int left, int right) {
int l = left;//左下标
int r = right;//右下标
//pivot 中轴值
int pivot = arr[(left + right) / 2];
int temp = 0;//临时变量,交换是使用
//while循环的目的:让比pivot小的值放到左边,大的放在右边。
while (l < r) {
//在pivot的左边一直找,直到找到大于等于privot的值,才退出
while (arr[l] < pivot) {
l += 1;
}
//privot 右边
while (arr[r] > pivot) {
r -= 1;
}
//l>=r,说明privot左右两边的值,已按照左边全部是小于等于privot的值,右边全部是大于等于privot的值
if (l >= r) {
break;
}
//交换
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//交换完后,发现arr[l]==pivot相等r--,前移
if (arr[l] == pivot) {
r -= 1;
}
//交换完后,发现arr[r]==pivot相等l++,后移
if (arr[r] == pivot) {
l += 1;
}
}
//如果l==r,必须l++,r--,否则栈溢出
if (l == r) {
l += 1;
r -= 1;
}
//向左递归
if (left < r) {
quickSort(arr, left, r);
}
//向右递归
if (right > l) {
quickSort(arr, l, right);
}
}
}

package com.at.sort;
import java.util.Arrays;
/**
* @author shkstart
* @creat ${2020}-${10}-${22}${14:54}
*/
//归并排序
public class MergetSort {
public static void main(String[] args) {
int arr[] = {8, 4, 5, 7, 1, 3, 6, 2};
int temp[] = new int[arr.length];//归并排序需要一个额外空间
mergeSort(arr, 0, arr.length - 1, temp);
System.out.println("递归排序后=" + Arrays.toString(arr));
}
//分+合的过程
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;//中间索引
//向左递归分解
mergeSort(arr, left, mid, temp);
//向右递归分解
mergeSort(arr, mid + 1, right, temp);
//合并
merge(arr, left, mid, right, temp);
}
}
//合并的过程
//left左边有序序列的初始索引
//right右边索引
//temp做中转的数组
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
System.out.println("合并次数:");//8个数,合并7次
int i = left;//初始化i,左边有序序列的初始索引
int j = mid + 1;//初始化j,右边有序序列的初始索引
int t = 0;//指向temp数组的当前索引
//1.
//先把左右两边(有序)的数据按照规则,填充到temp数组
//直到左右两边的有序序列,有一边处理完为止
while (i <= mid && j <= right) {
//如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素
//即将左边的当前元素,拷贝到temp数组
//然后后移,t++,i++
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t += 1;
i += 1;
} else {//反之,将右边有序序列的当前元素,填充到temp数组
temp[t] = arr[j];
t += 1;
j += 1;
}
}
//2.
//把有剩余数据的一边的数据依次全部填充到temp
while (i <= mid) {//说明左边的序列还有剩余元素,就全部填充到temp中
temp[t] = arr[i];
t += 1;
i += 1;
}
while (j <= right) {//说明右边的有序序列还有剩余元素,就全部填充到temp中
temp[t] = arr[j];
t += 1;
j += 1;
}
//3.
//将temp数组的元素拷贝到arr
//并不是每次都拷贝所有
t = 0;
int tempLeft = left;
//第一次合并tempLeft=0,right=1//第二次合并tempLeft=2,right=3
//最后一次合并tempLeft=0,right=7
System.out.println("tempLeft=" + tempLeft + ",right=" + right);
while (tempLeft <= right) {
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
}
}
}