快速排序

快速排序

快速排序是分治策略的另一个典型例子,对于任一待排序的序列 S 将其分为前后两个更小的子序列 S1和 S2,并对两个规模更小的序列进行递归的排序。待所有子序列递归的排序结束之后,整个序列S自然变成一个有序的序列。
如果是从小到大排序的序列
要求 S1 序列中的最大元素必须 小于等于 S2序列中最小的元素 既 Max(S1) <= Min(S2)

如果是从大到小排序的序列
要求 S1 序列中的最小元素必须 大于等于 S2序列中最大的元素 既 Min(S1) <= Max(S2)

平凡解:只含有单个元素的序列,本身就是有序序列。

以图例展示排序过程如下:
在这里插入图片描述

    public void QuickSort(int[] arr)
    {
        QuickSort(arr, 0, arr.Length - 1);
    }

    private void QuickSort(int[] arr, int low, int high)
    {
        if (low >= high)
        {
            return;
        }
        int mid = Partition(arr, low, high);
        QuickSort(arr, low, mid);
        QuickSort(arr, mid + 1, high);
    }

    private int Partition(int[] arr, int low, int high)
    {
        // 取最左侧的数据为轴点
        int pivot = arr[low];
        while (low < high)
        {
            while (low < high && pivot <= arr[high])
            {
                --high;
            }
            arr[low] = arr[high];

            while (low < high && arr[low] < pivot)
            {
                ++low;
            }
            arr[high] = arr[low];
        }
        arr[low] = pivot;

        return low;
    }

性能分析:
稳定性:快速排序算法是不稳定的,元素移动到轴点左右两侧的过程中,会破坏元素的先后顺序,出现相同元素前/后颠倒的情况,导致结果是不稳定的。

空间复杂度:只需要附加 O(1)的常数空间

时间复杂度:
最好情况:每次划分,轴点总是接近中间位置,此时达到最优的 O(nlogn)
最坏情况:每次划分极不均衡,如 轴点总是最大/最小的元素,导致所有元素均被划分到一侧,此时达到最坏情况 O(n^2),如对已排序的序列进行快速排序,如果每次都取第 0 个元素为轴点,则轴点一定是最小/最大的元素

如何减少最坏情况的发生,方案:每次随机选取序列中的一个元素作为轴点、两三个元素比较策略取其一等,但是任何方案都只能降低最坏情况的发生概率,而无法杜绝。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值