快速排序算法的基本思想是:
从数组中取出一个数,称之为基数(pivot)
遍历数组,将比基数大的数字放到它的右边,比基数小的数字放到它的左边。遍历完成后,数组被分成了左右两个区域
将左右两个区域视为两个数组,重复前两个步骤,直到排序完成
找pivot:
从 left 开始,遇到比基数大的数,记录其下标;再从 right 往前遍历,找到第一个比基数小的数,记录其下标;然后交换这两个数。继续遍历,直到 left 和 right 相遇。然后就和刚才的算法一样了,交换基数和中间值,并返回中间值的下标。
class Solution {
//快排
public int[] sortArray(int[] nums) {
quickSort(nums,0,nums.length-1);
return nums;
}
public void quickSort(int[] nums,int start,int end){
//如果区域内的数字少于2个,退出递归
if(start>=end) return;
//获得轴
int middle=getPivot(nums,start,end);
//递归
quickSort(nums,start,middle-1);
quickSort(nums,middle+1,end);
}
// 将nums从start到end分区,左边区域比基数小,右边区域比基数大,然后返回中间值的下标
public int getPivot(int[] nums,int start,int end){
//取第一个数为基数
int pivot=nums[start];
//左边界
int left=start+1;
//右边界
int right=end;
//移动两边界
while(left<right){
while(left<right && nums[left]<=pivot) left++;
while(left<right && nums[right]>=pivot) right--;
//此时左边界>pivot,右边界<pivot
//交换左右边界
if(left<right){
swap(nums,left,right);
left++;
right--;
}
}
//此时两种情况,left==right left>right
//单独判断left==right,nums[right]>pivot情况
if(left==right && nums[right]>pivot){
right--;
}
//此时都是left>right,轴right将数组分成两边界(start,right],(right,end]
//将基数和轴交换
swap(nums,start,right);
return right;
}
//交换方法
public void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}