C++ 排序函数 sort(),qsort()的用法

 想起来自己天天排序排序,冒泡啊,二分查找啊,结果在STL中就自带了排序函数sort,qsort,总算把自己解脱了~

所以自己总结了一下,首先看sort函数见下表:

   

函数名功能描述
sort对给定区间所有元素进行排序
stable_sort对给定区间所有元素进行稳定排序
partial_sort对给定区间所有元素部分排序
partial_sort_copy对给定区间复制并排序
nth_element找出给定区间的某个位置对应的元素
is_sorted判断一个区间是否已经排好序
partition使得符合某个条件的元素放在前面
stable_partition相对稳定的使得符合某个条件的元素放在前面

 

要使用此函数只需用#include <algorithm> sort即可使用,语法描述为:

sort(begin,end),表示一个范围,例如:

int _tmain(int argc, _TCHAR* argv[])
{
 int a[20]={2,4,1,23,5,76,0,43,24,65},i;
 for(i=0;i<20;i++)
  cout<<a[i]<<endl;
 sort(a,a+20);
 for(i=0;i<20;i++)
 cout<<a[i]<<endl;
 return 0;
}

输出结果将是把数组a按升序排序,说到这里可能就有人会问怎么样用它降序排列呢?这就是下一个讨论的内容.

 

一种是自己编写一个比较函数来实现,接着调用三个参数的sort:sort(begin,end,compare)就成了。对于list容器,这个方法也适用,把compare作为sort的参数就可以了,即:sort(compare).

1)自己编写compare函数:

bool compare(int a,int b)
{
      return a<b;   //升序排列,如果改为return a>b,则为降序

}

int _tmain(int argc, _TCHAR* argv[])
{
     int a[20]={2,4,1,23,5,76,0,43,24,65},i;
     for(i=0;i<20;i++)
       cout<<a[i]<<endl;
     sort(a,a+20,compare);
     for(i=0;i<20;i++)
       cout<<a[i]<<endl;
     return 0;
}

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

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

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;
              }
          }
};

接下来使用 sort(begin,end,compare(ASC)实现升序,sort(begin,end,compare(DESC)实现降序。

主函数为:

int main()
{
     int a[20]={2,4,1,23,5,76,0,43,24,65},i;
     for(i=0;i<20;i++)
         cout<<a[i]<<endl;
     sort(a,a+20,compare(DESC));
     for(i=0;i<20;i++)
         cout<<a[i]<<endl;
     return 0;
}

3)其实对于这么简单的任务(类型支持“<”、“>”等比较运算符),完全没必要自己写一个类出来。标准库里已经有现成的了,就在functional里,include进来就行了。functional提供了一堆基于模板的比较函数对象。它们是(看名字就知道意思了):equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>。对于这个问题来说,greater和less就足够了,直接拿过来用:

  • 升序:sort(begin,end,less<data-type>());
  • 降序:sort(begin,end,greater<data-type>()).

int _tmain(int argc, _TCHAR* argv[])
{
      int a[20]={2,4,1,23,5,76,0,43,24,65},i;
      for(i=0;i<20;i++)
          cout<<a[i]<<endl;
      sort(a,a+20,greater<int>());
      for(i=0;i<20;i++)
          cout<<a[i]<<endl;
      return 0;
}

4)既然有迭代器,如果是string 就可以使用反向迭代器来完成逆序排列,程序如下:

int main()
{
     string str("cvicses");
     string s(str.rbegin(),str.rend());
     cout << s <<endl;
     return 0;
}

 

 

qsort():

原型:
_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*));

解释:    qsort ( 数组名 ,元素个数,元素占用的空间(sizeof),比较函数) 
比较函数是一个自己写的函数  遵循 int com(const void *a,const void *b) 的格式。
当a b关系为 >  <  = 时,分别返回正值 负值 零 (或者相反)。
使用a b 时要强制转换类型,从void * 转换回应有的类型后,进行操作。 
数组下标从零开始,个数为N, 下标0-(n-1)。

实例:
int compare(const void *a,const void *b)
{
     return *(int*)b-*(int*)a;   
}

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

相关:

1)why你必须给予元素个数?

因为阵列不知道它自己有多少个元素

2)why你必须给予大小?

因为 qsort 不知道它要排序的单位.

3)why你必须写那个丑陋的、用来比较俩数值的函式?

因为 qsort 需要一个指标指向某个函式,因为它不知道它所要排序的元素型别.

4)why qsort 所使用的比较函式接受的是 const void* 引数而不是 char* 引数?

因为 qsort 可以对非字串的数值排序.

转自:https://blog.csdn.net/zzzmmmkkk/article/details/4266888 

转载于:https://www.cnblogs.com/dylancao/p/9150447.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.net core 实现默认图片

web 上 如果图片不存在 一般是打xx 这时候 一般都是会设置默认的图片 代替 现在用中间件的方式实现统一设置 一次设置 全部作用 .net core 实现默认图片 Startup 文件 app.UseDefaultImage(defaultImagePath: Configuration.GetSection("defaultImagePath").Va…

spring cloud config将配置存储在数据库中

转载请标明出处&#xff1a; https://blog.csdn.net/forezp/...本文出自方志朋的博客 Spring Cloud Config Server最常见是将配置文件放在本地或者远程Git仓库&#xff0c;放在本地是将将所有的配置文件统一写在Config Server工程目录下&#xff0c;如果需要修改配置&#xff0…

VMware虚拟机VMware Authorization Service不能启动问题

出现VMware Authorization Service不能启动问题&#xff0c;注意要在安装VMware Player时使用管理员权限转载于:https://www.cnblogs.com/mingzhang/p/9152873.html

PHP替换回车换行的三种方法

一个小小的换行&#xff0c;其实在不同的平台有着不同的实现&#xff0c;为什么要这样&#xff0c;世界是多样的&#xff01;本来在Unix世界换行用/n来代替换行&#xff0c;Windows为了体现不同&#xff0c;就用/r/n&#xff0c;更有意思的是&#xff0c;Mac中又用了/r。所以&a…

全球的weex资源都在这里

WeeX FAQ QQ: Weex大前端 516682889Weexbox&#xff1a; 943913583WeeX相关资源 weex官方资源 weex官网 Weex Market 已挂 : 一个提供 Weex 第三方组件的网站&#xff0c;您可以在这里找到你需要的 Weex 组件。 Playground : Playground在线&#xff0c;直接在线编写代码并预览…

初步解决博客园代码高亮的一个方案

今天我要推荐的是一个免费而且支持markdown语法的软件——Typora 它有很多优点&#xff0c;支持多种类型代码的高亮风格&#xff0c;方便的排版处理&#xff0c;支持Latex等&#xff0c;最重要的一点是真正做到了所见即所得ヽ(&#xff9f;∀&#xff9f;)&#xff92;(&#x…

git工作原理

工作区&#xff1a;就是你在电脑里能看到的目录。暂存区&#xff1a;英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件&#xff08;.git/index&#xff09;中&#xff0c;所以我们把暂存区有时也叫作索引&#xff08;index&#xff09;。版本库&#xf…

【前端基础进阶】JS-Object 功能详解

Object.assign(target,source1,source2,...)该方法主要用于对象的合并&#xff0c;将源对象source的所有可枚举属性合并到目标对象target上,此方法只拷贝源对象的自身属性&#xff0c;不拷贝继承的属性。Object.assign方法实行的是浅拷贝&#xff0c;而不是深拷贝。也就是说&am…

解决“无法从套接字读取更多数据”

重启下Oralce服务即可。转载于:https://www.cnblogs.com/fkeyta/p/9153297.html

网页下载Google Play 的App

网页下载Google Play 的App 文章目录[点击展开](?)[] 前言 当你想在google play上下载某个应用&#xff0c;而无奈手机的系统并没有安装google servicess&#xff0c;此刻是否有些捉急&#xff1f; 本文分享的是一个网站&#xff0c;它可以无需手机而直接通过网页下载Google P…

“硬核”代码重构

在学习编程的路上&#xff0c;相信大家这几个词一定不少听&#xff0c;什么 面相对象、封装继承多态、内功心法21种设计模式 等等 。但是却很少用到&#xff0c;或者说用到的都是被动使用。大牛们在写代码前早就构思好了&#xff0c;接口&#xff0c;基类等等。自己写代码的时候…

上传jar包到nexus私服

进入maven管理页面&#xff0c;登录管理员账号 完成后可以进入对应目录下查看pom依赖 通过maven的方式depoly 在maven的conf/setting.xml 配置nexus私服的管理账号 在servers标签下添加server <server><id>nexus-snapshots</id><username>repouser<…

手把手教你写高质量Android技术博客,画图工具,录像工具,Markdown写法

前言 作为程序员&#xff0c;写博客是一件很有意义的事情&#xff0c;可以加深自己对技术的理解&#xff0c;可以结交更多的朋友&#xff0c;记录自己的技术轨迹&#xff0c;而且分享可以让更多的人从中受益&#xff0c;独乐乐不如众乐乐嘛。 但是要写好博客也不是件容易的事&a…

【Android】RxJava的使用(四)线程控制 —— Scheduler

前言 经过前几篇的介绍&#xff0c;对RxJava对模式有了一定的理解&#xff1a;由Observable发起事件&#xff0c;经过中间的处理后由Observer消费。&#xff08;对RxJava还不了解的可以出门左拐&#xff09;之前的代码中&#xff0c;事件的发起和消费都是在同一个线程中执行&am…

sed: -e expression #1, unknown option to `s'解决办法

报错如下&#xff1a; sed: -e expression #1, char 13: unknown option to s 需要替换的行为&#xff1a; monitor.urlhttp://192.168.25.100:8443/rest 查询资料得知&#xff0c;报错是因为替换的字符串包含有分隔符/ 所以这行改一下分隔符就可以解决问题了 改成感叹号!或者|…

Linux常用开发环境软件-Redis安装(docker环境下)

linux&#xff0c;docker安装RabbitMQ版本 1、从docker官网仓库下载安装RabbitMQ镜像 官网地址&#xff1a;https://hub.docker.com/ docker pull redis:4.0.8  //后面是版本,Tag Name 2、启动Docker Redis镜像 docker run -d -p 6379:6379 redis:4.0.8  启动镜像&#xff…

以当天日期时间,打包目录

#备份/data目录#!/bin/bash DATEdate %Y-%m-%d-%H:%M:%S tar cvf /mnt/resource/script/prod_master_data.$DATE.tar.gz /data[root111 script]# ll total 2536 -rw-r--r-- 1 root root 2590720 Feb 22 21:46 prod_master_data.2019-02-22-21:46:53.tar.gz转载于:https://blog.…

lvs+keepalived详解

常用软件安装及使用目录 资源链接&#xff1a;https://pan.baidu.com/s/15rFjO-EnTOyiTM7YRkbxuA 网盘分享的文件在此 官网&#xff1a;http://www.linuxvirtualserver.org/index.html 中文资料 LVS项目介绍 http://www.linuxvirtualserver.org/zh/lvs1.html …

微信自动打卡

要有第二台安卓 手机&#xff0c;打开usb、adb调试&#xff0c;永不锁屏&#xff0c;永不休眠&#xff0c;手机安装了微信并至少成功登陆过一次&#xff0c; 一台不关机的电脑&#xff0c;手机连接电脑&#xff0c;Appium服务器保持启动&#xff0c;在开始菜单 设定好任务计划程…

利用反射做类参数的校验

需求描述 业务需求描述&#xff1a;对webservice接口参数校验 代码实现 /*** 字符串长度校验* * param str* param len* return 合法(true),不合法(false)*/public static boolean check(String str, int len) {if (null ! str && str.length() > len) {return fals…