快速排序

描述

快速排序(有时称为分区交换排序)是一种高效的排序算法。由英国计算机科学家Tony Hoare于1959年开发并于1961年发表,它在现在仍然是一种常用的排序算法。如果实现方法恰当,它可以比主要竞争对手(归并排序和堆排序)快两到三倍。

其核心的思路是取第一个元素(或者最后一个元素)作为分界点,把整个数组分成左右两侧,左边的元素小于或者等于分界点元素,而右边的元素大于分界点元素,然后把分界点移到中间位置,对左右子数组分别进行递归,最后就能得到一个排序完成的数组。当子数组只有一个或者没有元素的时候就结束这个递归过程。

其中最重要的是将整个数组根据分界点元素划分成左右两侧的逻辑,目前有两种算法。

leetcode示例

912.排序数组
给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:

1 <= nums.length <= 50000
-50000 <= nums[i] <= 50000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-an-array

C++代码实现

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        quicksort(nums,0,nums.size()-1);
         return nums;
    }
// 第一种快排
private:
    void quicksort(vector<int>& nums,int left, int right){
        if(left >= right)  return;
        int li = left + 1;//小于某值nums[left]的最右侧值下标
        int hi = right;
        while(li <= hi){
            if(nums[li] > nums[left]){
                swap(nums,li,hi);
                hi--;
            }else{
                li++;
            }
        }
        li--;
        swap(nums,li,left);
        quicksort(nums,left, li - 1);
        quicksort(nums, li + 1, right);
    }
    //第二种快排
    void quicksort(vector<int>& nums,int left, int right){
        if(left >= right)  return;
        int li = left;//小于某值nums[left]的最右侧值下标
        int hi = left+1;
        while(hi <= right){
            if(nums[hi] < nums[left]){
                swap(nums,li+1,hi);
                li++;
            }
            hi++;
        }
        swap(nums,li,left);
        quicksort(nums,left, li - 1);
        quicksort(nums, li + 1, right);

    }
    void swap(vector<int>& nums,int m,int n){
        int temp = nums[m];
        nums[m] = nums[n];
        nums[n] = temp;

    }
}

第二种,不用hi来标记大于分界点元素的最左侧,而是只用一个li来标记最右侧。在遍历整个数组的过程中,如果发现了一个小于等于分界点元素的元素,就和li+1位置的元素交换,然后li自增,这样可以保证li的左侧一定都是小于等于分界点元素的,遍历到最后li的位置就是新的分界点位置,和最开始的分界点元素位置互换。

时间复杂度在最佳情况是O(nlogn),但是如果分界点元素选择不当可能会恶化到O(n2),但是这种情况比较少见(比如数组完全逆序),如果随机选择分界点的话,时间复杂度能够稳定在O(nlogn)。另外如果元素中相同元素数量比较多的话,也会降低排序性能。

空间复杂度在O(logn)水平,属于堆栈调用,在最坏的情况下空间复杂度还是O(n),平均情况下复杂度是O(logn)
快速排序是不稳定的,因为包含跳跃式交换元素位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值