快速排序的Java实现
面试很可能让你手撕快速排序,掌握思想是很必要的。
主体思想
从数列中挑出一个元素,称为 “基准”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
具体步骤
第一次循环过程如下:
- 先定义一个基准,就以最左边的数为基准(pivot);
- 再定义两个变量,i表示从左找到比基准大的数,j表示从左找到比基准小的数;
- 先从右边找,找到后赋值给i的位置,再从左边找,找到后赋值给j的位置;
- 直到i==j,把基准pivot赋值给i的位置,则左边<基准<右边;
- 再对基准左边进行相同操作,右边亦是如此;
代码:
快排代码:
public class QuickSort {
public void quickSort(int[] arr, int left, int right){
//必须要写结束条件,否则会栈溢出
if (left>=right){
return;
}
int i=left;
//定义最左边的是为基准(pivot)
int pivot = arr[left];
int j = right;
//循环条件, 保证基准右边的数都大于它,左边的数都小于它
while (i<j){
//找到最右边第一个小于基准数的数
while (i<j && arr[j] > pivot){
j--;
}
if(i<j ){
// i++是因为赋完值,i这个位置已经判断过了,就是arr[j],必小于基准
arr[i++] = arr[j];
}
//找到最左边第一个大于基准数的数
while (i<j && arr[i]< pivot){
i++;
}
if(i<j ){
// j--是因为赋完值,j这个位置已经判断过了,就是arr[i],必小大于基准
arr[j--] = arr[i];
}
}
//结束循环必是i==j, 把基准pivot放到i就可以了;
arr[i] = pivot;
quickSort(arr,left, i-1);
quickSort(arr,i+1, right);
}
}
测试代码:
public static void main(String[] args) {
int[] nums = {3,4,1,6,8,7,0,9,2,5};
new QuickSort().quickSort(nums,0,nums.length-1);
System.out.println(Arrays.toString(nums));
}
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]