【蓝桥杯ALGO-59】快速排序 Java版

柔情痞子 提交于 2020-02-21 11:22:37

试题 算法训练 快速排序

资源限制
时间限制: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];
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!