手写java快排(快速排序)代码——双边循环法,本人亲测哈哈!!
package com.abc.backend.algo;
import java.util.Arrays;
/**
* 快排(双边循环法)
*/
public class QuickSort {
// 精髓在于,每一次传入的startIndex与endIndex都是基于递归中的“上一次”传进来的,而不是“最开始”的那两个值。
public static void func(int[] nums, int startIndex, int endIndex){
/** 结束条件 */
/*
关于 startIndex>endIndex 的情况简介 ——————
一、说明递归的上一层中的"startIndex == pivotIndex == endIndex"。上一层中的“分治方法”中现象如下:
(1)上一层中,因为startIndex == pivotIndex,所以startIndex > pivotIndex-1,而pivotIndex-1就是递归下一层的endIndex。 所以会导致startIndex>endIndex的情况
(2)上一层中,因为 endIndex == pivotIndex,所以pivotIndex+1 > endIndex ,而pivotIndex+1进入递归下一层的startIndex。所以会导致startIndex>endIndex的情况
二、而startIndex == pivotIndex == endIndex时,说明nums中只剩一个数了,就应该终止执行递归了
*/
if(startIndex >= endIndex){ //注意这里是“ >= ”
return;
}
int pivotIndex = funcExt(nums, startIndex, endIndex);
/** 分治 */
func(nums, startIndex, pivotIndex-1);
func(nums, pivotIndex+1, endIndex);
}
public static int funcExt(int[] nums, int startIndex, int endIndex){
//取基准数(第一个或者随机,这里取第一个)
int pivot = nums[startIndex];
int left = startIndex;// 换个词好理解
int right = endIndex;//换个词好理解
while (left != right){
while(left != right && nums[right] > pivot){ // 循环挪指针过程中,首先保证left与right不相遇。如果相遇,则跳出循环,交换pivot与“重合数”
right--;
}
while(left != right && nums[left] <= pivot){ // 循环挪指针过程中,首先保证left与right不相遇。如果相遇,则跳出循环,交换pivot与“重合数” // 这里有个等号,因为pivot与num[left]每轮开始时都相等
left++;
}
/** right和left都停了,交换 */
//{
// System.out.println("交换前数组:" + Arrays.toString(nums));
// System.out.println("交换前索引:[0][1][2][3][4][5][6][7]");
// System.out.println("交换索引位:" + left + "<<<>>>" + right);
//}
if(left != right){ // left与right相遇了,就不需要自己与自己交换了,浪费资源
int t = nums[right];
nums[right]=nums[left];
nums[left]=t;
}
//{
// System.out.println("交换后数组:" + Arrays.toString(nums));
// System.out.println("==================");
//}
}
/** right==left,即left与right相遇,相遇的位置叫“重合数”,交换pivot与“重合数” */
nums[startIndex]=nums[left];
nums[left]=pivot;
return left;
}
public static void main(String[] args) {
int[] nums = {4,7,3,5,6,2,8,1};
// int[] nums = {8,1};
QuickSort.func(nums, 0, nums.length-1);
System.out.println(Arrays.toString(nums));
}
}