手撕快排完整代码

2024 年 8 月 28 日 星期三
/
7
1
AI 生成的摘要

手撕快排完整代码

import java.util.Scanner;
public class Main {
    public static void quickSort(int nums[],int l,int r){
        if(l>=r) return;
        int i = l-1,j = r+1;
        //下标中值作为基准值
        int x = nums[l+r>>1];
        //排序:基准左边的值都小于基准值,基准右边的值都大于基准值
        while(i<j){
            while(nums[++i]<x);//在左边寻找第一个大于等于基准的值,可能会找到基准右边
            while(nums[--j]>x);//在右边寻找第一个小于等于基准的值,可能会找到基准左边
            //找值时可能越过基准值,所以要判断
            if(i<j){
                int tem = nums[i];
                nums[i] = nums[j];
                nums[j] = tem;
            }
        }
        //边界见注解
        quickSort(nums,l,j);
        quickSort(nums,j+1,r);
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int nums[] = new int[n];
        for(int i = 0;i<n;i++){
            nums[i] = in.nextInt();
        }
        quickSort(nums,0,nums.length-1);
        for(int i=0;i<nums.length;i++){
            System.out.print(nums[i]+" ");
        }
    }
}

习惯用 C++写题之后换成 Java 是真难受,输入输出都很麻烦 写个完整代码以后参考

关于两个while 循环:

在代码中,ij 是用来寻找两个元素并交换它们的指针。i 逐步向右移动,找到一个大于或等于基准值 x 的元素;j 逐步向左移动,找到一个小于或等于基准值 x 的元素。

ij 相遇时,表示左边和右边的所有元素已经按基准值 x 排好了序。所以,交换发生后,nums[i]nums[j] 位置是正确的。

然后,递归调用 quickSort(nums, l, j)quickSort(nums, j + 1, r) 来处理左边和右边的子数组。


关于边界:

为什么是 j 而不是 i 作为边界?

i 是用于从左边寻找比基准大的元素,它可能会跨越基准的正确位置,而 j 总是会停在一个有效的位置(即最后一个小于基准值的元素的位置)。

在排序完成后,j 的位置是基准值应该放置的位置,因为 j 是最后一个小于等于基准值的元素的索引。

ij 可能会交错,而递归时需要将基准元素的左右两部分分别处理。所以基准的右侧部分从 j + 1 开始处理,而左侧部分到 j

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...