C++中sort()与qsort()相关用法的总结

C++中sort()与qsort()相关用法的总结

关于排序问题,平时我们在工作中会经常遇到,刚好最近看了几个关于库函数排序的博客,觉得写得都不错,为了方便今后能够方便使用,今天就花点时间总结一下(其实前段时间对于sort的用法也写过两个博客),sort()与qsort()的时间复杂度都为O(nlogn),都算是比较好的排序方法
关于sort使用方法的讨论(把数组排成最小的数)
华为OJ-奥运会排行榜C++

关于排序
qsort()

排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用。 这就是qsort函数(全称quicksort)。它是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,其时间复杂度为n*log(n)

原型:
_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*));
参数: 1 待排序数组,排序之后的结果仍放在这个数组中
    2 数组中待排序元素数量
    3 各元素的占用空间大小(单位为字节)
     4 指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数)
解释:    qsort ( 数组名 ,元素个数,元素占用的空间(sizeof),比较函数) 
比较函数是一个自己写的函数  遵循 int com(const void *a,const void *b) 的格式。
当a b关系为 >  <  = 时,分别返回正值 负值 零 (或者相反)。
使用a b 时要强制转换类型,从void * 转换回应有的类型后,进行操作。 
数组下标从零开始,个数为N, 下标0-(n-1)
//对int型数组排序
#include <iostream>
#include <cstdlib>
using namespace std;

int compare(const void *a,const void *b)
{
     return *(int*)b-*(int*)a;//降序
}

int main()
{
     int a[]={2,4,1,23,5,76,0,43,24,65};
     int i, len = sizeof(a) / sizeof(int);
     for(i=0;i<len;i++)
        cout<<a[i]<< ' ';
     cout << endl;
     qsort(a,len,sizeof(int),compare);
     for(i=0;i<len;i++)
        cout<<a[i]<< ' ';
     return 0;
}

qsort要求提供一个自己定义的比较函数。比较函数使得qsort通用性更好,有了比较函数qsort可以实现对数组、字符串、结构体等结构进行升序或降序排序。

//对char型数组排序
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

int compare(const void *a, const void *b)
{
     return *(char*)a - *(char*)b; //升序
}

int main()
{
     char a[]= "hello";
     int i, len = strlen(a);
     for(i=0;i<len;i++)
        cout<<a[i]<< ' ';
     cout << endl;
     qsort(a,len,sizeof(char),compare);
     for(i=0;i<len;i++)
        cout<<a[i]<< ' ';
     return 0;
}

//对double型数组排序
#include <iostream>
#include <cstdlib>

using namespace std;

int compare(const void *a,const void *b)
{
     return *(double*)a > *(double*)b ? 1 : -1;//升序
}

int main()
{
     double a[]={2,4,1,23,5,76,0,43,24,65};;
     int i, len = sizeof(a) / sizeof(double);
     for(i=0;i<len;i++)
        cout<<a[i]<< ' ';
     cout << endl;
     qsort(a,len,sizeof(double),compare);
     for(i=0;i<len;i++)
        cout<<a[i]<< ' ';
     return 0;
}
/*在对浮点或者double型的一定要用三目运算符,因为要是使用像整型那样相减的话,如果是两个很接近的数则可能返回一个很小的小数(大于-1,小于1),而cmp的返回值是int型,因此会将这个小数返回0,系统认为是相等,失去了本来存在的大小关系*/
sort()

Sort()函数是c++一种排序方法之一,学会了这种方法也打消我学习c++以来使用的冒泡排序和选择排序所带来的执行效率不高的问题!因为它使用的排序方法是类似于快排的方法,时间复杂度为n*log(n),执行效率较高!
要使用此函数只需用#include

两个参数版本

sort(begin,end)对于只有两个参数的sort,默认是升序排列,如果对于复杂的数据类型排序,需要重载operator<运算符

三个参数版本

调用三个参数的sort:sort(begin,end,compare)就成了。对于list容器,这个方法也适用,把compare作为sort的参数就可以了,即:sort(compare).
自己编写compare函数:
bool compare(int a,int b)
{
return a<b; //升序排列,如果改为return a>b,则为降序
}
下面这个是3个参数的一个典型问题
关于sort使用方法的讨论(把数组排成最小的数)
其实对于这么简单的任务(类型支持“<”、“>”等比较运算符),完全没必要自己写一个类出来。标准库里已经有现成的了,就在functional里,include进来就行了。functional提供了一堆基于模板的比较函数对象。它们是(看名字就知道意思了):equal_to、not_equal_to、greater、greater_equal、less、less_equal。对于这个问题来说,greater和less就足够了,直接拿过来用:

升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()).
使用类描述第三个参数

更进一步,让这种操作更加能适应变化。也就是说,能给比较函数一个参数,用来指示是按升序还是按降序排,这回轮到函数对象出场了。

为了描述方便,我先定义一个枚举类型EnumComp用来表示升序和降序。很简单:

enum Enumcomp{ASC,DESC};

然后开始用一个类来描述这个函数对象。它会根据它的参数来决定是采用“<”还是“>”。数组也可以使用sort函数排序

#include <iostream>
#include <algorithm>
enum Enumcomp{ASC,DESC};
class compare
{
private:
    Enumcomp comp;
public:
    compare(Enumcomp c):comp(c) {};
    bool operator () (int num1,int num2)
    {
        switch(comp)
        {
         case ASC:
            return num1 < num2;
         case DESC:
            return num1 > num2;
        }
        return true;//为了防止告警,其实没有实际用途
    }
};

int main()
{
    int myints[] = {32, 14, 25, 47, 29, 11, 98, 56};
    std::sort(myints, myints + sizeof(myints) / sizeof(int), compare(DESC));
    for (int x : myints)
        std::cout << x << " ";
    return 0;
}
//接下来使用 sort(begin,end,compare(ASC)实现升序,
//sort(begin,end,compare(DESC)实现降序。

在这里插入图片描述

//不用switch
#include <iostream>
#include <algorithm>
struct myclass
{
    bool operator()(int i, int j){return i > j;}
} myobject;

int main()
{
    int myints[] = {32, 14, 25, 47, 29, 11, 98, 56};
    std::sort(myints, myints + sizeof(myints) / sizeof(int), myobject);
    for (int x : myints)
        std::cout << x << " ";
    return 0;
}

参考博文:
https://blog.csdn.net/zzzmmmkkk/article/details/4266888/
https://blog.csdn.net/zhao888789/article/details/79186619

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑着的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值