排序算法-快速排序

概述

快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

每一次排序都会把选出的key,放入数组中间,左边都是比key小的元素,右边都是比key大的元素,然后以key为分割点,对 [0, k-1] 和 [k+1, length] 进行如上操作,直到数组中只有一个元素。

时间复杂度

时间复杂度为:O(nlogn)

算法稳定性

快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a[i]和a[j],重复上面的过程,直到i>j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 5 3 3 4 3 8 9 10 11, 现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j] 交换的时刻。

示例代码

/**
 * 快速排序
 * @author 吴庆龙
 * Date: 2018/8/2
 * Time: 11:17
 */
public class QuickSort {

    public static void main(String[] args) {

        int[] array = {7,3,2,4,1,8,0,9,5,6};
        sort(array, 0, array.length - 1);

        for (int i : array) {
            System.out.print(i + " ");
        }
        System.out.println();

    }

    private static void sort(int[] array, int left, int right) {

        // 递归终止条件
        if (left >= right) {
            return;
        }

        // 左边索引
        int l = left;
        // 右边索引
        int r = right;

        // 关键字
        int key = array[left];

        while (l < r) {

            // 从右向左查找比 key 小的数
            while (l < r && key <= array[r]) {
                r--;
            }
            if (l < r) {
                // 把数放入array[l]的位置(小的放到数组的左边)
                array[l] = array[r];
                l++;
            }

            // 从右向左查找比 key 大的数
            while (l < r && key >= array[l]) {
                l++;
            }
            if (l < r) {
                // 把数放入array[r]的位置(大的放到数组的右边)
                array[r] = array[l];
                r--;
            }

        }

        // 确定key的位置, 并赋值
        array[l] = key;

        sort(array, left, l - 1);
        sort(array, l + 1, right);

    }

}
点赞