当前位置: 首页 > 编程日记 > 正文

C中的qsort函数和C++中的sort函数的理解与使用

一、qsort()函数

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

参数解释:1、待排序数组首地址;2、数组中待排序元素数量;3、各元素的占用空间的大小;4、指向函数的指针,用于确定排序的顺序。

说明:qsort函数是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,时间复杂度为O(n*logn)。

qsort要求提供比较函数用来确定排序的顺序(升序、降序),比较函数使得qsort通用性更好,可以对数组、字符串、结构体数进行排序。如int cmp(const void *a, const void *b)中有两个元素作为参数(参数的格式不能变的。)返回一个int值,如果比较函数返回大于0,qsort就认为a > b,返回小于0,qsort就认为a < b。

1、qsort中几种常见的cmp函数

1.1、对int类型数组排序

int num[100];
int cmp(const void *a, const void *b)
{return *(int *)a - *(int *)b;
}qsort(num, 100, sizeof(int), cmp);

1.2、对char类型数组排序

char num[100];
int cmp(const void *a, const void *b)
{return *(char *)a - *(char *)b;
}qsort(num, 100, sizeof(char), cmp);

1.3、对double类型数组排序

double num[100];
int cmp(const void *a, const void *b)
{return *(double *)a > *(double *)b;
}qsort(num, 100, sizeof(double), cmp);

1.4、对结构体数组一级排序

struct In
{double data;int other;
}s[100]
//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种,参考上面的例子写 
int cmp( const void *a ,const void *b)
{return (*(In *)a)->data > (*(In *)b)->data ? 1 : -1;
}qsort(s,100,sizeof(In),cmp); 

1.5、对结构体数组二级排序

struct In
{int x;int y;
}s[100];
//按照x从小到大排序,当x相等时按照y从大到小排序 
int cmp( const void *a , const void *b )
{struct In *c = (In *)a;struct In *d = (In *)b;if(c->x != d->x) return c->x - d->x;elsereturn d->y - c->y;
}qsort(s,100,sizeof(In),cmp);       

1.6、对字符串进行排序

struct In{int data;char str[100];
}s[100];
//按照结构体中字符串str的字典顺序排序 
int cmp ( const void *a , const void *b )
{return strcmp( (*(In *)a)->str , (*(In *)b)->str );
}
qsort(s,100,sizeof(In),cmp); 

1.7、计算几何中求凸包的cmp

int cmp(const void *a,const void *b) //重点cmp函数,把除了1点外的所有点,旋转角度排序 
{struct point *c=(point *)a;struct point *d=(point *)b;if( calc(*c,*d,p[1]) < 0) 
    return 1;else if( !calc(*c,*d,p[1]) && dis(c->x,c->y,p[1].x,p[1].y) < dis(d->x,d->y,p[1].x,p[1].y)) //如果在一条直线上,则把远的放在前面 return 1;else
    return -1; }

2、拓展知识点

one、为啥子使用qsort函数要指定排序元素的大小?

ans:这是个脑残的问题,给个脑残的答案吧。因为qsort需要根据元素的大小来进行排序。

two、 所使用的比较函式接受的是 const void* 类型?

ans:因为考虑到qsort的通用性,这样可以对数组,结构体数组等类型进行排序了。

二、sort()函数

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

要使用上述函数必须加上头文件algorithm。

1、sort(begin,end)

小例子

#include<algorithm>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函数降序排序,ok!就像qsort中一样,我们需要自定义一个比较函数cmp(返回值为bool类型)。

2、重载的sort函数-带比较函数的sort(begin,end,cmp)

定义比较函数的方法

2.1、常用方法

下面的比较函数可以实现降序排序:

bool cmp(int a,int b)
{return a>b;      
}

2.2、使用枚举类型enum来定义升序或者降序排序。

//ASC升序,DESC降序
enum Cmp{ASC,DESC};

2.3 定义一个比较类,来描述排序的顺序。

class compare
{private:Cmp comp;public:compare(Cmp c):comp(c) {};bool operator () (int num1,int num2) {switch(comp){case ASC:return num1<num2;case DESC:return num1>num2;}}
};

测试一下:

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

了解一下即可,因为比较麻烦,根据实际情况使用。

2.4、使用functional头文件中的比较对象。

functional提供了一堆基于模板的比较函数对象。equal_to<Type>、not_equal_to<Type>、greater<Type>、greater_equal<Type>、less<Type>、less_equal<Type>。对于这些比较对象,我们可以望文生义就知道它们的意思了。

for example:

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

三、qsort函数和sort函数的PK。

1、cmp函数不同

返回值类型不同,qsort函数的cmp返回值类型为int,sort函数的cmp返回值为bool。

参数不同,sort函数的cmp可以直接是参与比较的引用类型,而qsort是严格的空指针类型。

比较表达式不同,qsort中的cmp使用的是“-”号,而sort中的cmp使用的是“>”。

2、性能的区别

sort函数是c++中标准模板库的的函数,在qsort()上已经进行了优化,根据情况的不同可以采用不同的算法,所以较快。在同样的元素较多和同样的比较条件下,sort()的执行速度都比qsort()要快。另外,sort()是类属函数,可以用于比较任何容器,任何元素,任何条件。

相关文章:

机器学习新闻综述:2019年AI领域不得不看的6篇文章

作者 | Limarc Ambalina翻译 | 火火酱&#xff0c;编辑 | Carol出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;在这篇机器学习新闻综述中&#xff0c;我们将回顾一些2019年以来在人工智能各个领域广泛传播或产生影响的重大新闻。此外&#xff0c;我们还将…

GDB attach到进程

要调试守护进程等已经启动的进程或是调试陷于死循环的进程可以使用attach命令 格式 attach pid C语言代码 #include <stdio.h> int main(void) { int marks[10]; int i; for(i0;i<12;i) { scanf("%d",&marks[i]); …

Chrome使用技巧和编辑框拖动怪问题。

常用快捷键&#xff1a;ctrlshiftt 重新打开刚关闭的网页ctrlh 打开历史记录ctrl 放大。ShiftEscape 查看任务管理器据说Chrome能调整编辑区大小&#xff0c;我没发现。倒发现Chrome一个问题&#xff0c;选中编辑框中的文字&#xff0c;一直拖动鼠标&a…

Linux中断研究

2019独角兽企业重金招聘Python工程师标准>>> 研究linux系统&#xff0c;不管是做驱动、协议栈还是进程调度等等&#xff0c;都离不开中断。这说明&#xff0c;要想编写正确的linux代码&#xff0c;不了解中断是不行的。 话说曾几何时&#xff0c;在大学的课堂里&…

linux环境内存分配原理

Linux的虚拟内存管理有几个关键概念&#xff1a; Linux 虚拟地址空间如何分布&#xff1f;malloc和free是如何分配和释放内存&#xff1f;如何查看堆内内存的碎片情况&#xff1f;既然堆内内存brk和sbrk不能直接释放&#xff0c;为什么不全部使用 mmap 来分配&#xff0c;munm…

大脑芯片公司Neuralink计划在人脑内植入芯片,他们到底想干什么?

作者 | James Murphy翻译 | 火火酱&#xff0c;编辑 | Carol出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;说实话&#xff0c;科幻电影在遇到Neuralink时也不得不甘拜下风。2019年7月&#xff0c;埃隆马斯克(Elon Musk)宣布&#xff0c;他的公司正在研发…

判断链表是否存在环(及其延伸)

有一个单链表&#xff0c;其中可能有一个环&#xff0c;也就是某个节点的next指向的是链表中在它之前的节点&#xff0c;这样在链表的尾部形成一环。问题&#xff1a;1、如何判断一个链表是不是这类链表&#xff1f;2、如果链表为存在环&#xff0c;如果找到环的入口点&#xf…

iOS跳转到各种系统设置界面

定位服务 定位服务有很多APP都有&#xff0c;如果用户关闭了定位&#xff0c;那么&#xff0c;我们在APP里面可以提示用户打开定位服务。点击到设置界面设置&#xff0c;直接跳到定位服务设置界面。代码如下&#xff1a; //定位服务设置界面 NSURL *url [NSURL URLWithString:…

Linux内存管理大图(第三稿)

网友画的还不错就转了 &#xff0c;该作者一共画了3版 v0.1 v0.2 v0.3 原文地址&#xff1a;http://bbs.chinaunix.net/thread-2018659-1-1.html

VNC的安装与使用

VNC的安装与使用。 说明&#xff1a;文章内容比较简单&#xff0c;献给那些初学者作为参考。 文章分为两部分&#xff0c;第一部分为VNC简介&#xff0c;第二部分为VNC的安装与使用。 文章为小弟结合书籍与小弟的实际操作总结出来的&#xff0c;如有错误与疏漏之处…

百度「AI战疫」:首次开源肺炎CT影像分析AI模型,让诊断从分钟到秒

自疫情爆发以来&#xff0c;多家科技公司纷纷加入了抗击疫情的战役中。 其中&#xff0c;排查疫情是这场战役的重中之重&#xff0c;而 CT 影像已成为新冠肺炎筛查和病情诊疗的重要依据。 然而&#xff0c;在当前疫情诊疗的关键时期&#xff0c;存量患者和新增患者总体数量庞…

Linux_DNS服务器

目录 目录DNS DNS ServerServerSite Master DNS ServerForward DomainReverse Resolution Slave DNS ServerForward lookupReverse lookupSplit DNS ServerDNS DNS(Domain Name System&#xff0c;域名系统)&#xff0c;在Internet上作为域名和IP地址映射的一个分布式数据库&am…

多场景下的AI疫情防控“天网”:解读云边端联动下的全栈AI技术

在全民抗疫的特殊时期下&#xff0c;伴随着春运返潮&#xff0c;企业陆续复工&#xff0c;从重点防控的机场、火车站等场所&#xff0c;到学校、企业、社区等密集型场所&#xff0c;都是不能忽视的地点。除了人工逐一测量体温排查外&#xff0c;我们还发现&#xff0c;在人员复…

DHCP配置与DHCP中继代理2

实验二&#xff1a;<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />Step1、配置DHCP中继代理1) 打开“管理工具”→“路由和远程访问”窗口&#xff0c;启用路由和远程访问&#xff0c;按向导提示完成操作。<?xml:namespac…

查看CPU是i386架构和x86_64架构

查看处理器是32位还是64位 #cat /proc/cpuinfo 检查flags行中有没有lm标记&#xff0c;lm是Long Mode的简写&#xff0c;表示支持64位模式。 #getconf LONG_BIT 输出&#xff1a;32 #getconf WORD_BIT 输出&#xff1a;32 32位的系统中int类型和long类型一般都是4字节&…

malloc一次性最大能申请多大内存空间

受用户态内存地址空间的限制。64 位系统下分配几个 T 不成问题。 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。作者&#xff1a;zz matrix链接&#xff1a;http://www.zhihu.com/question/20836462/answer/22833295来源&#xff1a;知乎考…

MD5算法之C#程序

MD5算法比较特别&#xff0c;最适合用汇编语言来写&#xff0c;好多高级语言对之无能无力或效率极低。 比如我最开始尝试用Python和Euphoria编写&#xff0c;发现不太容易。相比而言&#xff0c;C#作为C家簇 中新兴的一门.net语言&#xff0c;功能比较全面。花了一晚上的工夫终…

unix环境汇编语言常用工具

汇编器 MASM&#xff1a;微软的汇编器不支持unix NASM&#xff1a;unix环境下兼容微软平台 GAS&#xff1a;GNU 的免费软件包&#xff0c;unix环境下最流行跨平台汇编器 安装GNU汇编器 检查binunits RedHat #rpm -qa |grep binunits Debian #dpkg -l|grep binunit 下载地…

用Python远程登陆服务器的最佳实践

来源 | Python编程时光&#xff08;ID: Cool-Python&#xff09;在使用 Python 写一些脚本的时候&#xff0c;在某些情况下&#xff0c;我们需要频繁登陆远程服务去执行一次命令&#xff0c;并返回一些结果。在 shell 环境中&#xff0c;我们是这样子做的。$ sshpass -p ${pass…

Exchange Server 2013 LAB Part 4.内部客户端访问

关于Exchange服务器内部客户端访问的更详细介绍&#xff0c;请参考Exchange Server 2010链接&#xff1a;http://xutonglin.blog.51cto.com/8549515/1390715每个组织在AD林中都至少有一台客户端访问服务器和一台邮箱服务器。另外&#xff0c;每个AD站点中都必须至少有一台客户端…

VirtualBox安装64位Linux

VirturlBox安装64位的Linux 原因 virtualbox 本身不带 64 位支持&#xff0c;它的 64 位支持依赖于通过cpu虚拟技术把cpu的64位指令直接映射过去。 所以&#xff0c;要支持64位必须&#xff1a; 1.你的cpu支持64位。 2.你的cpu支持虚拟化&#xff0c;并且你的bios支持把cpu虚…

6个步骤,告诉你如何用树莓派和机器学习DIY一个车牌识别器!(附详细分析)...

作者 | Robert Lucian Chiriac翻译 | 天道酬勤&#xff0c;编辑 | Carol出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;几个月前&#xff0c;作者开始考虑让汽车能够具备检测和识别物体的能力。他很喜欢这个主意&#xff0c;因为已经见识到了特斯拉的能力…

推荐bpython

可能很多人都对ipython比较熟悉&#xff0c;但是我这里要推荐的是bpython&#xff0c;我发现用起来更加顺手。详细的信息可以从其官方网站上获得。下面介绍几个主要的feature&#xff08;使用系统为Linux&#xff09;&#xff1a;1. 语法高亮&#xff1a;2. 自动提示&#xff0…

几个定制 iTerm2 的 tip

重装 Mac 才想起来很多配置没有备份过, 找起来麻烦, 所以记一下 按文本开头搜索命令 一个是 Bash 里按上下键直接查找历史, 匹配开头相同的内容最开始是我朋友在 Matlab 下用到提到想要这个方案, 一起找了结果真有于是记录一下配置: ➤➤ cat ~/.inputrc "\e[A":hist…

从1的补码说起计算机的数制

字节换算 bit(b)位 字节(byte)8位 -128~127 0&#xff5e;255 半字2字节16位 -32768~32767 0&#xff5e;65,535 字(word)4字节32位 -2147483848~2147483647 0&#xff5e;4,294,967,295 双字8字节64位 -9223372036854775808~9223372036854775807 0&#xff5e;18,446,744…

类:认识类的继承

先新建一个 VCL Forms Application 工程, 代码中就已经出现了两个类:一个是 TForm 类; 一个是 TForm1 类; TForm1 继承于 TForm.TForm 是 TForm1 的父类; TForm1 是 TForm 的子类. Codeunit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, C…

机器会成为神吗?

作者 | Roman Wiligut翻译 | 天道酬勤&#xff0c;编辑 | Carol出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;看着科技的飞速发展&#xff0c;我们越来越想知道&#xff0c;到底科技发展有没有极限呢&#xff1f;在我看来&#xff0c;没有。至少在我们的…

1、Linux汇编——初识汇编

2019独角兽企业重金招聘Python工程师标准>>> 前序 本来想Qt能继续坚持下来&#xff0c;可是绕了一大圈&#xff0c;最终还是选择回到学期伊始的Linux汇编编程上来。鉴于图书馆只能借到这本书&#xff0c;虽然不厚&#xff0c;但是内容还是比较实用丰富&#xff0c;作…

汇编语言调用Linux系统调用

首先查找系统调用文件 #find / -name unistd.h /root/linux/include/unistd.h /usr/include/linux/unistd.h /usr/include/sys/unistd.h /usr/include/bits/unistd.h /usr/include/unistd.h 查看系统调用值 /root/linux/include/unistd.h #define __NR_setup 0 /* use…

为什么说Transformer就是图神经网络?

作者 | Chaitanya Joshi译者 | Kolen出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;前言有些工程师朋友经常问我这样一个问题&#xff1a;“图深度学习听起来很棒&#xff0c;但是现在是否有非常成功的商业案例&#xff1f;是否已经在实际应用中部署&#xff1f;”除…