个人觉得快速排序挺难理解的,但是效率确实很高,也很实用,相信大家也想看看别人是如何写速排序的代码,以下就是我的代码,思路都在注释里了,有什么不解可以评论区沟通交流。
import java.util.Arrays;
public class QuickSortTest {
public static void main(String[] args) {
int[] arr = {9, 7, 5, 3, 1};
System.out.println(Arrays.toString(arr));
quickSort(arr, 0,arr.length-1 );
System.out.println(Arrays.toString(arr));
// System.out.println(Arrays.toString(arr));
// quickSort2(arr, 0,arr.length-1 );
// System.out.println(Arrays.toString(arr));
int[] arrs = new int[80000];
for (int i = 0; i < arrs.length; i++) {
arrs[i] = (int) (Math.random() * 800000);
}
long l = System.currentTimeMillis();
quickSort2(arrs, 0, arrs.length - 1);
long l1 = System.currentTimeMillis();
System.out.println("耗时为 "+ (l1 - l) +" 毫秒");
System.out.println(arrs.length);
System.out.println(Arrays.toString(arrs));
}
public static void quickSort(int[] arr, int left, int right) {
//该方法是以中间值为标准数
int l = left; //左指针
int r = right; //右指针
int poivt = arr[(left + right) / 2]; //中轴的值
int temp;//临时变量,作为交换时使用
while (l < r) {
if (arr[l] < poivt) {//在pivot的左边一直找,找到大于等于pivot值,才退出
l++;
}
if (arr[r] > poivt) {//在pivot的右边一直找,找到小于等于pivot值,才退出
r--;
}
//如果l >= r说明pivot 的左右两的值,已经按照左边全部是
//小于等于pivot值,右边全部是大于等于pivot值
if (l == r) {
break;
}
//交换位置
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
//如果r--不理解也可以换成l++,l后移,但是效率会略微降低
if (arr[l] == poivt) {
r--;
}
//如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
//同理也可以换成r--
if (arr[r] == poivt) {
l++;
}
}
if (l == r) { //如果 l == r, 必须l++, r--, 否则为出现栈溢出
l++;
r--;
}
if (left < r) {//向左递归
quickSort(arr, left, r);
}
if (right > l) {//向右递归
quickSort(arr, l, right);
}
}
public static void quickSort2(int[] arr, int start, int end) {
//该方法是以第一个值为标准数
//如果开始位置和结束位置重合,实际上就是一个数字,所以开始位置一定要比结束位置小,而且不能相等
if (start < end) {
//设定标准数,也就是快速排序的过程中,和标准数进行比较,通常用第一个数字即可
//注意这里用的是arr[start],按说在第一次的时候是0,应该写成arr[0],但是不可以
//因为快速排序是一个递归的操作,第二次进来的时候,就不是arr[0]了
int stand = arr[start];
//开始找开始位置和结束位置
//我们知道快速排序其实就是有一个开始位置和一个结束位置,当开始位置比选定的标准数字大的时候,就会替换掉
//结束位置的数字,这个时候结束位置的下标开始向前移动,然后如果结束位置的数字比标准数字,则替换开始位置的数字
//在循环的过程中如果开始位置/结束位置的数字 不比标准数字大或者小,这个时候开始位置和结束位置就会向后/向前移动
//开始位置
int low = start;
//结束位置
int high = end;
while (low < high) {
//这个时候我们已经找定了开始位置和结束位置
//第一次是要拿高位和低位进行比较,如果高位比标准数字大,则高位则向前移动一位
while (low < high && arr[high] >= stand) {
high--;
}
//当然了并不是所有高位数字都比低位大,如果比低位要小,则这个数字要覆盖低位的数字
arr[low] = arr[high];
//然后这个时候低位开始移动,如果低位比标准数字小,则低位的下标向后移动一位
while (low < high && arr[low] <= stand) {
low++;
}
//当然了并不是所有时候低位都比标准数字要小,如果比标准数字大的话,这个时候就要替换掉高位的数字
arr[high] = arr[low];
}
//到了这一步就会出现一个情况,低位和高位相同,那么这个位置就用标准数字去替换
//这里low和high实际上是相同的数字,所以写哪个都无所谓
arr[low] = stand;
//然后第一轮排序完毕,我们就会发现以标准数字为分界线,我们有两个序列了,这个时候,我们就调用递归来分别对两个序列进行排序
//先做低位递归
quickSort2(arr, start, low - 1);
//然后再做高位递归
quickSort2(arr, low + 1, end);
}
}
}
这是打印的结果图