排序数组
就是纯粹的一个快速排序的题,主要的注意点就是 选取元素的时候要随机 这样能够保证时间复杂度控制在O(nlogn).同时切记,快速排序的最坏情况下会降为复杂度O(n^2)
主要的就是理解快排的原理和手撕代码的流畅性吧.具体的一些小细节在代码中已经全部注释体现
public class Solution006 {
public static void main(String[] args) {
int[] nums = new int[]{3,2,1,5,6,4};
QuickSort(nums);
for(int i: nums){
System.out.print(i+",");
}
}
public static void QuickSort(int[] nums){
if(nums==null || nums.length<2) return;
QuickSort(nums,0,nums.length-1);
}
//对nums[left,right]区间进行排序操作
public static void QuickSort(int[] nums,int left,int right){
if(left<right){
//随机选一个数和最后一个数做交换
swap(nums,left+(int)(Math.random()*(right-left+1)),right);
//划分值等于区域的左边界和右边界 这个数组返回的就是这两个边界的下标
int[] p = partition(nums,left,right);
//此时[left,less]是小于区 [less+1,more]是等于区 [more+1,right]是大于区
//可以说明more就是这个随机数的位置
QuickSort(nums,left,p[0]-1);//小于的区域进行快排
QuickSort(nums,p[1]+1,right);//大于的区域进行快排
}
}
//这个函数 用于将数进行左右区分 中间部分是等于划分值的元素区域 并且返回区分的左右边界
public static int[] partition(int[] nums,int left,int right){
int less = left-1;//小于区的右边界 注意是右边界
int more = right;//大于区的左边界 注意是左边界
//left表示当前数的位置 arr[right]表示的是我们设置的划分值
while(left<more){
if(nums[left]<nums[right]){//当前数<划分值
//当前数和右边界+1位置做交换,然后右边界右移一位
swap(nums,++less,left++);
}else if(nums[left]>nums[right]){//当前数>划分值
//当前数和左边界-1位置做交换,然后左边界左移一位
swap(nums,--more,left);
}else{
left++;
}
}
//此时num[right]是那个用于判断的数 但是它在比它的元素的右边 所以把它交换过去
swap(nums,more,right);//这more是大于区的左边界
//所以此时就是这么个情况[left,less]是小于区 [less+1,more]是等于区 [more+1,right]是大于区
return new int[]{less+1,more};
}
public static void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}