第四篇:【初学】C++的sort使用技巧以及快排实现

sort()简介

sort() 是 C++ 标准库中的一个排序函数,定义在 a l g o r i t h m algorithm algorithm 头文件中。
它的排序时间复杂度是 O ( n l g n ) O(nlgn) O(nlgn),远胜于普通的冒泡排序和选择排序。
现在介绍其函数重载、使用方法以及快速排序的具体实现。

sort()使用方法

默认排序(不传入函数参数)

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main(){
    vector<int> example={11,42,3,24};
    sort(example.begin(),example.end());//传入迭代器或指针,指向开头和结尾,默认是升序排序
    int example1[]={22,33,11};
    sort(example1,example1+3);//注意,若手动管理地址,则要求左闭右开,与迭代器同
}

传入函数参数

可以调用C++的预定义比较器,储存在 f u n c t i o n a l functional functional头文件中

std::greater<T>//降序排序,把T换成需要比较的类型
std::less<T>//升序排序,默认,可省略

传入参数格式示例

#include<iostream>
#include<algorithm>
#include<vector>
#include<functional>
using namespace std;

int main(){
    vector<int> example={11,42,3,24};
    sort(example.begin(),example.end());//传入迭代器或指针,指向开头和结尾,默认是升序排序
    int example1[]={22,33,11};
    sort(example1,example1+3,greater<int>());//注意,若手动管理地址,则要求左闭右开,与迭代器同
    for(auto& a:example){
        cout<<" "<<a;
    }
    cout<<endl;
    for(auto& a:example1){
        cout<<" "<<a;
    }
    return 0;
}

输出结果:
 3 11 24 42
 33 22 11

自定义比较函数写法:

#include<iostream>
#include<algorithm>
#include<vector>
#include<functional>
using namespace std;
bool cmp(int a, int b) {
    return a>b;//返回值为真,则传入顺序为真,即a在前,b在后,此为降序排序
}
int main(){
    vector<int> example={11,42,3,24};
    sort(example.begin(),example.end());//传入迭代器或指针,指向开头和结尾,默认是升序排序
    int example1[]={22,33,11};
    sort(example1,example1+3,cmp);//自定义函数不需要括号,只需要传入函数名
    for(auto& a:example){
        cout<<" "<<a;
    }
    cout<<endl;
    for(auto& a:example1){
        cout<<" "<<a;
    }
    return 0;
}

输出结果:
 3 11 24 42
 33 22 11

记忆技巧:若返回值为真,则代表a在前面,b在后面
故想要升序排序则返回a>b,想要降序排序则返回a<b

快速排序实现

快排的原理就是二分化处理数组,以实现遍历logn次就能使数组有序。
(一般地,在时间复杂度领域提到log都是指以2为底)

下面提供一个快排的升序实现代码

#include<iostream>
#include<utility>
using namespace std;
inline 
void mysort(int* arr,int left,int right){//闭区间
    if(left==right)
        return;
    int middle=(left+right)/2;
    int flag=arr[middle];
    int cut=0;
    for(int l=left,r=right;;l++,r--){
        while(arr[l]<flag)//尽量创造条件丢过去,不取等,否则当flag为最大值时,会因为cut=right而出错
            l++;
        while(arr[r]>flag)
            r--;
        if(l<r)
            swap(arr[r],arr[l]);
        else{
            cut=r;
            break;
        }
    }
    //当循环break后,知道r的右边都是大于flag的数字,l同理
    //把cut判给左边
    mysort(arr,left,cut);
    mysort(arr,cut+1,right);
    return;
}
int main(){
    int example1[]={1,42,3,24,5,74,29,58,22,33,11};
    mysort(example1,0,10);
    for(auto& a:example1){
        cout<<" "<<a;
    }
    return 0;
}



输出结果: 1 3 5 11 22 24 29 33 42 58 74

快排实现时,要主要好边界条件以及比较条件。

比较flag数时,取等会发生什么情况呢

考虑极端情况下,若flag数为最大值,那么r就会停留在右边(r去找小于flag的数字),l也会到最右边

如此一来,cut+1就越界了。

然而,理论上,flag取数组中数字时,完全可以保证起码r右边有一个数字

因此,就发现必须让flag参与交换之中,才能保证当flag为最值时不越界。

当flag不为最值时,显然r右侧必定有一个数,不会越界

若cut取l左侧,思考过程类似,不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值