试题 算法训练 快速排序
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
快速排序是最经常使用的一种排序方式,对于给定的n个数组成的一个数组,请使用快速排序对其进行排序。
现给定一序列,请用快速排序将其按升序排序并输出。
输入格式
第一行一个数N。
第2~N+1行每行一个数,表示给定序列。
输出格式
共N行,每行一个数,表示所求序列。
样例输入
5
1
4
2
3
4
样例输出
1
2
3
4
4
数据规模和约定
共10组数据。
对100%的数据,N<=10^5,所有数均为非负数且在int范围内。
分析
对于已经排好序,或者接近排好序的情况,会进入最差情况,时间复杂度衰退到 O(n^2),采用三数中值分割法选取分区点(pivot),避免出现时间复杂度退化到最糟糕情况。
参考:工具类算法–快排的优化(Java)
Java 代码:
import java.io.*;
public class Main {
private static int[] a;
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(in.readLine());
a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = Integer.parseInt(in.readLine());
}
quickSort(a, 0, n - 1);
for (int i = 0; i < n; i++) {
System.out.println(a[i]);
}
}
public static void quickSort(int[] a, int left, int right) {
if (left >= right) {
return;
}
// 三数中值分割法选取分区点
int pivot = median3(a, left, right);
int i = left;
int j = right - 1;
while (i < j) {
// 在 L 指针和 R 指针遇到等于枢纽元的元素时,让两个指针都停下来
while (i < j && pivot > a[++i]) {
}
while (i < j && pivot < a[--j]) {
}
if (i < j) {
swap(a, i, j);
}
}
swap(a, i, right - 1);
quickSort(a, left, i - 1);
quickSort(a, i + 1, right);
}
private static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
//三数中值分割法
private static int median3(int[] a, int i, int j) {
//对三个数进行排序
int m = (i + j) >> 1;
if (a[m] < a[i]) {
swap(a, i, m);
}
if (a[j] < a[i]) {
swap(a, i, j);
}
if (a[j] < a[m]) {
swap(a, j, m);
}
//将分区点放在j - 1;
swap(a, m, j - 1);
return a[j - 1];
}
}
来源:CSDN
作者:FreeTechLiu
链接:https://blog.csdn.net/weixin_40608613/article/details/104376791