快排模板题题解(完美解决边界问题)

547 阅读1分钟

1.1快排

步骤:

  1. 划分区域
  2. 找分界点q[l], q[r]q[l + r >> 1]
  3. 递归处理两段

核心步骤分解:

9837C714461EB017C047A7F86AC2F1EC.png

例1:快速排序

给定你一个长度为 nn 的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 nn。

第二行包含 nn 个整数(所有整数均在 1∼1091∼109 范围内),表示整个数列。

输出格式

输出共一行,包含 nn 个整数,表示排好序的数列。

数据范围

1≤n≤1000001≤n≤100000

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5
import java.util.Scanner;
class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int a[] = new int[n];

        for(int i = 0; i < n; i ++) a[i] = in.nextInt();

        quickSort(a, 0, n - 1);

        for (int i = 0; i < n; i++) System.out.print(a[i] + " ");

    }

    public static void quickSort(int q[], int l, int r){
        if (r <= l) return;

        int i = l - 1, j = r + 1;
        int x = q[l + r >> 1];

        while(i < j){
            do i++; while(q[i] < x);
            do j--; while(q[j] > x);
            if (i < j){
                int temp = q[i];
                q[i] = q[j];
                q[j] = temp;
            }
        }
        quickSort(q, l, j);
        quickSort(q, j + 1, r);
    }
}

例2 - 第k个数(快排 + 快选)

给定一个长度为 nn 的整数数列,以及一个整数 kk,请用快速选择算法求出数列从小到大排序后的第 kk 个数。

输入格式

第一行包含两个整数 nn 和 kk。

第二行包含 nn 个整数(所有整数均在 1∼1091∼109 范围内),表示整数数列。

输出格式

输出一个整数,表示数列的第 kk 小数。

数据范围

1≤n≤1000001≤n≤100000, 1≤k≤n1≤k≤n

输入样例:

5 3
2 4 1 5 3

输出样例:

3
import java.util.Scanner;

/**
 * @author Lil
 * @date 2021/4/26 22:31
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int[] q = new int[n];
        for(int i = 0; i < n; i ++) q[i] = sc.nextInt();
        System.out.println(quickSort(q, 0, n -1, k));
    }
    public static int quickSort(int[] q, int l, int r, int k) {
        if (l >= r) return q[l];
        int i = l - 1, j = r + 1;
        int x = q[l + r >> 1];
        while (i < j) {
            do i++; while (q[i] < x);
            do j--; while (q[j] > x);
            if (i < j) {
                int temp = q[i];
                q[i] = q[j];
                q[j] = temp;
            }
        }
        // 求出 SL 的长度(分界点 - 左边界 + 1)
        int SL = j - l + 1;
        if (k <= SL) return quickSort(q, l, j, k);
        else return quickSort(q, j + 1, r, k - SL);//右半边的第k个数为k - SL
    }
}