关于快速排序的相关知识

关于快速排序的相关知识

快速排序主要由四步完成。
1、选择一个数
2、做partition操作
3、分别对左右两个小区间做相同处理
4、直到小区间有序为止
具体过程如下图所示:
在这里插入图片描述

代码操作如下

private static void quickSortInternal(long[] array,
                                          int lowIndex,
                                          int highIndex) {
        // 由于是闭区间,所以,区间内个个数需要加个 1
        int size = highIndex - lowIndex + 1;
        if (size <= 1) {
            return;
        }

        // 选择其中一个数(选最左边的) —— array[lowIndex]
        // 执行 partition,小的放左,大的放右
        // keyIndex 是经过 partition 之后,选出来的数最终所在下标
        int keyIndex = partition(array, lowIndex, highIndex);
        // 分别对左右区间进行相同的处理 —— 递归方法
        quickSortInternal(array, lowIndex, keyIndex - 1);
        quickSortInternal(array, keyIndex + 1, highIndex);
    }

其中的partition操作主要有三种方式:
1、Hover法
2、挖坑法
3、左右法

Hover法

private static int partitionHover(long[] array, int lowIndex, int highIndex) {
        int leftIndex = lowIndex;
        int rightIndex = highIndex;
        // 选择的数是最左边的一个
        long key = array[lowIndex];
        // 选择了最左边,从右边先走

        // 停止条件 leftIndex == rightIndex
        // 循环的继续的条件 leftIndex < rightIndex
        while (leftIndex < rightIndex) {

            while (leftIndex < rightIndex && array[rightIndex] >= key) {
                rightIndex--;
            }
            // 说明 [rightIndex] 遇到了小的了

            while (leftIndex < rightIndex && array[leftIndex] <= key) {
                leftIndex++;
            }
            // 说明 [leftIndex] 遇到了大的了

            swap(array, leftIndex, rightIndex);
        }

        swap(array, lowIndex, leftIndex);

        return leftIndex;
    }

挖坑法

private static int partition挖坑(long[] array, int lowIndex, int hightIndex) {
        int leftIndex = lowIndex;
        int rightIndex = hightIndex;

        long key = array[lowIndex];

        while (leftIndex < rightIndex) {
            while (leftIndex < rightIndex && array[rightIndex] >= key) {
                rightIndex--;
            }

            array[leftIndex] = array[rightIndex];

            while (leftIndex < rightIndex && array[leftIndex] <= key) {
                leftIndex++;
            }

            array[rightIndex] = array[leftIndex];
        }

        array[leftIndex] = key;

        return leftIndex;
    }

左右法

private static int partition前后(long[] array, int lowIndex, int highIndex) {
        int separateIndex = lowIndex + 1;
        for (int i = lowIndex + 1; i <= highIndex; i++) {
            if (array[i] < array[lowIndex]) {
                swap(array, i, separateIndex);
                separateIndex++;
            }
        }

        swap(array, lowIndex, separateIndex - 1);

        return separateIndex - 1;
    }

关于快速排序的性能
时间复杂度:
最好情况 最坏情况 平均情况
O(n * log(n)) O(n^2) O(n * log(n))
空间复杂度:
最好情况 最坏情况 平均情况
O(log(n)) O(n) O(log(n))

关于快速排序的优化

1、partition选择挖坑法
2、数量比较少时,不够快(当区间内的个数少于某个阈值时,使用插排法)
3、优化选择特殊数的方式
(1)随机选
(2)挑几个数,选大小为中间值的(三数取中)
4、相同的值特殊处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值