快速排序

15 篇文章 3 订阅

Leetcode 912 数组排序

给你一个整数数组 nums,请你将该数组升序排列。
在这里插入图片描述
方法一: 快速排序
参考: https://blog.csdn.net/wthfeng/article/details/78037228

基本思想:将基点放入他正确的位置,将数组划分为两份: 大于基点的,小于基点的。然后对两份分别进行递归,直至所有的点都位于合适的位置。

  1. 确定出归条件,当区间只含有一个元素时,即:不用继续排序了。 所以出归条件为: low >= high.
  2. 先将右边界向左扫描,遇到小于基点的元素,停止扫描
  3. 再将左边界向右扫描,遇到大于基点的元素,停止扫描
  4. 交换这时的左右边界元素
  5. 继续重复上述2-5,直至左右边界相遇,则跳出循环,交换这时的右边界和基点元素。
  6. 然后在对左半边进行递归排序
  7. 最后对右半边进行递归排序
class Solution {
public:

    void quickSort(vector<int>& nums,int low, int high){
        if(low>=high){
            return;
        }
        int base = nums[low];
        int i = low;  // [l, i-1] <= base
        int j = high; // [j+1, high] >=base
        while(i<j){
            while(base <= nums[j] && i <j){
                j--;
            }
            while(base >= nums[i] && i <j){
                i++;
            }
            swap(nums[i],nums[j]);
        }
        swap(nums[low],nums[j]);

        quickSort(nums,low,j-1);
        quickSort(nums,j+1,high);
    }
    vector<int> sortArray(vector<int>& nums) {
        if(nums.size()==0){
            return nums;
        }else{
            int low = 0;
            int high = nums.size()-1;
            quickSort(nums, low, high);
            return nums;
        }
    }

};

改进方法:
1.在最后几个元素时,采用插入排序
2.快速排序最差情况,退化了O(n^2). 数组有序时。这时采用随机标定点

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        int low = 0;
        int high = nums.size() - 1;
        quickSort(nums,low,high);
        return nums;
    }

    void quickSort(vector<int>& nums, int low, int high){
        if(low>=high){
            return;
        }
        int i = low;
        int j = high;
        // 随机选取标定点
        swap(nums[low],nums[rand()%(high-low+1)+low]);
        int base = nums[low];

        while(i < j){
            while(nums[j]>=base && i < j){
                j--;
            }
            while(nums[i]<=base && i < j){
                i++;
            }
            swap(nums[i],nums[j]);
        }
        swap(nums[low],nums[j]);

        quickSort(nums, low, j-1);
        quickSort(nums, j+1, high);
    }
};

三路快排

当数组中含有大量重复元素时,三路快排优势明显。
基本思想:
将数组分成3部分:

  1. 小于v,其区间为[l+1, lt]
  2. 等于v, 其区间为[lt+1,i-1]
  3. 大于v,其区间为[gt,r]
    在这里插入图片描述
    当arr[i] <v时, swap(arr[lt+1], arr[i]); lt++; i++;
    当arr[i] = v 时,i++;
    当arr[i] >v 时,swap(arr[gt-1], arr[i]); gt–;
    直到i >= gt 时停止遍历,swap(arr[lt], arr[l]).
    然后在对非等于v的部分进行递归三路排序。
class Solution {
public:
    void quickSort(vector<int>& arr, int l, int h){
        if(l>=h){
            return;
        }
        int j = l;  // [l+1, l] < v . 现在是空集
        int k = h+1;  // [k, h] > v . 现在是空集
        int v = arr[l];
        int i = j+1; // [j+1, i-1] = v . 现在是空集
        while(i<k){
            if(arr[i]<v){
                swap(arr[i],arr[j+1]);
                i++;
                j++;
            }else if(arr[i] == v){
                i++;
            }else{
                swap(arr[k-1],arr[i]);
                k--;
            }
        }
        swap(arr[j],arr[l]);

        quickSort(arr, l, j-1);
        quickSort(arr,k,h);
    }

    void sortColors(vector<int>& nums) {
        int l = 0;
        int h = nums.size()-1;
        quickSort(nums, l, h);
    }
};

注意,j, k ,i 的初始赋值
需要使三个区间为空集

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值