快速排序

1、快速排序

引例:三色旗思想:

问题描述:

有一个只由 0,1,2 三种元素构成整数数组,请使用交换、原地排序而不是使用计数进行排序

解题思路:

定义两个下标 left 和 right;

left 的含义:使数组中下标 <=left 的部分都比 1 小,left 的初始值为 -1;

right 的含义:使数组中下标 >=right 的部分都比 1 大,right 的初始值为 n;

从index = 0 开始遍历;

根据 index 所指向的值分别进行不同的操作;

如果 vec[index] = 0,swap(vec[index++],vec[++left];

(这里 index++ 的原因是 index 左边不可能有 ==2 的数据了)

如果 vec[index] = 1,index++;

如果 vec[index] = 2,swap[vec[index],vec[--right]);   

代码实现:

以 {0,1,2,0,0,1,2,1,0} 为例:

#include<iostream>

#include<vector>

using namespace std;

void Quick(vector<int>&vec,int L,int R){

    int left = L - 1;

    int right = R + 1;

    int temp = 1;

    int index = 0;

    while(index < right){

        if(vec[index] == temp){

            index++;            

        }

        else if(vec[index] < temp){

            swap(vec[index++],vec[++left]);

        }

         else {

             swap(vec[index], vec[--right]);

         }

    }

}

int main(){

    vector<int>vec = {0,1,2,0,0,1,2,1,0};

    Quick(vec,0,vec.size()-1);

    for(auto it : vec){

        cout<<it<<" ";

    }

    return 0;

}

思想:

1)三色旗问题:找一个基准值(这里选取待排序数组最左边的那个值),然后将待排序数组分为三部分;

第一部分:数据全部小于基准值

第二部分:数据全部等于基准值

第三部分:数据全部大于基准值

2)将第一部分和第三部分分别进行三色旗问题处理,直到 index >= j, 即数组有序

#include<iostream>

#include<vector>

using namespace std;

pair<int,int> Quick(vector<int>& vec, int L, int R) {

    int i = L - 1;

    int j = R + 1;

    int temp = vec[L];

    int index = L;

    while (index < j) {
         if (vec[index] > temp) {

            swap(vec[index], vec[--j]);

         }

         else if (vec[index] < temp) {

            swap(vec[index++], vec[++i]);

         }

         else {

            index++;

         }

    }

    return make_pair(i, j);

}

void quickSort(vector<int>& vec, int L, int R) {

    if (L >= R)return;

    pair<int, int>p = Quick(vec, L, R);

    quickSort(vec, L, p.first);

    quickSort(vec, p.second, R);

}

int main() {

    vector<int>vec = { 0,1,2,0,0,1,2,1,0 };

    quickSort(vec, 0, vec.size() - 1);

    for (auto it : vec) {

        cout << it << " ";

    }

    return 0;

}

平均时间复杂度:O(n*logn)

稳定性:不稳定  实例  5  7  7  1  1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值