package 剑指offer;
import java.util.Arrays;
public class t122手撕快速排序forlearn {
public static void quick_sort(int[] number,int start,int end) {
//只有start<end才会执行
if(start<end){
//定义基准值
int mid_num=number[start];
//定义左右指针
int left=start;
int right=end;
//循环(左指针小于右指针时才循环)
while (left<right){
//首先右指针动,只要右边的数大于基准数 ,右指针左移
//这里可以有一个写= ,但另一边不能写
while (left<right && mid_num<=number[right]){
right--;
}
number[left]=number[right];
//相反
while (left<right && number[left]<mid_num){
left++;
}
number[right]=number[left];
}
// 此时left=rignt 就差mid_num了,所以要把midnum赋给number[left]或者number[right]
number[left]=mid_num;
//递归 left此处不用再动了 已经排好了
quick_sort(number,start,left-1);
quick_sort(number,left+1,end);
}
}
public static void main(String[] args){
int[] arr=new int[]{0,1,6,9,2,5,3,7,4,8};
quick_sort(arr,0, arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
第二种写法:(有partition函数)
package 剑指offer;
import java.util.Hashtable;
import java.util.Random;
public class t122_1手撕快速排序 {
public int[] sortArray(int[] nums) {
quicksort(nums,0,nums.length-1);
return nums;
}
public void quicksort(int[] nums,int start,int end){
if(start<end){
//中间值 也就是上一轮选取的中间值
int pivot =partition(nums, start, end);
quicksort(nums,start,pivot-1);
quicksort(nums,pivot+1,end);
}
}
/**
* 分区函数
* @param nums
* @param start
* @param end
* @return
*/
private int partition(int[] nums,int start,int end){
//是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。
//j
int random =new Random().nextInt(end-start+1)+start;
swap(nums,random,end);
//p1指针
int small =start-1;
//此时中间值就是
//这里使用 i++与 ++i是一样的,但是++i内存更节省 ;但在for循环中 i++与++i
for (int i=start;i<end;i++){
if (nums[i]<nums[end]){
small++;
swap(nums,i,small);
}
}
small++;
swap(nums,small,end);
return small;
}
/**
* 交换函数
* @param nums
* @param index1
* @param index2
*/
private void swap(int[] nums, int index1, int index2) {
if(index1!=index2){
int temp =nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
}
}
}
记住这个partiton 函数 他也是解决返回数组第K个大的数的钥匙