1.1快排
步骤:
- 划分区域
- 找分界点
q[l]
,q[r]
或q[l + r >> 1]
- 递归处理两段
核心步骤分解:
例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
}
}