【C/C++】qsort函数的使用方法和细节
函数概述
qsort 为quick sort的简写,意为快速排序,主要用于对各种数组的排序,在头文件stdlib.h中。
因为数组的元素可能是任何类型的,甚至是结构或者联合,所以必须高数函数qsort如何确定两个数组元素哪一个“更小”,这就需要我们给出比较的规则,即什么算大,什么算小。
通过编写比较函数可以为函数qsort提供这些信息。当给定两个指向数组元素的指针p和q时,比较函数必须返回一个整数。如果*p小于*q,那么返回的数为负数;如果*p等于*q,那么返回0.如果*p大于*q,返回正数。
函数原型
void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *))
函数描述
函数的形式参数从左到右分别为:
指向要排序数组的第一个元素的指针base(如果只是要对数组的一段区域进行排序,那么要是base指向这段区域的第一个元素。)在一般情况下,base就是数组的名字;
nmemb是要排序元素的数量(不一定是数组中元素的数量);
size是每个数组元素的大小,用字节来衡量;
compar为指向比较函数的指针。
比较函数的实现
比较函数的实现是qsort函数能否正确实现的重点。
编写比较函数并没有想象中的那么容易。函数qsort要求它的形式参数类型为void *,但我们不能通过void *型的指针访问数组的成员;我们需要指向要比较元素的类型的指针。为了解决这个问题,我们将在比较函数内部把p与q赋给相应对应类型的指针变量。由于常量指针不能赋值给变量。所以在声明对应指针变量时应该加上const关键字。
下面是一个比较整型数组的比较函数的例子。
int compare(const void *p, const void *q)
{
const int *p1 = p;
const int *q1 = q;
if (*p1 < *q1)
return -1;
else if (*p1 == *q1)
return 0;
else
return 1;
}
当然除了把用const指针变量的方法,还可以使用强制类型转换的方式来达到这个目的。
int compare(const void *p,const void *q)
{
if(*(int *)p<*(int *)q)
return -1;
else if(*(int *)p==*(int *)q)
return 0;
else
return 1;
}
还可以进一步精简
int compare(const void *p,const void *q)
{
return *(int *)p-*(int *)q;
}
需要注意的点:比较元素是指针的比较函数的实现。
如果待比较的元素是指针(虽然我们一般不会比较指针的大小,但是我们经常需要对指针代表的空间比较大小,比如比较一个字符串数组的大小,每个字符串都由一个指针代表),那么比较函数的实现就比较麻烦了。
首先我们需要明确的是,比较函数中的两个指针必须要指向需要比较的两个元素。如果这两个元素是指针而不是一个实体,那么这两个指针应该是指向指针的指针。
这里我们以一个比较字符串的比较函数举例:
int compare(const void *p,const void *q)
{
return strcmp(*(char **)p,*(char **)q);
}
9/25补充
昨天刷题的时候发现一个和qsort有关的坑。
如果在写cmp函数时使用return *(int *)p-*(int *)q;简写,而比较函数比较后返回的是一个int值,这种写法在比较元素是整型的时候没有什么问题,但是如果比较的元素是double时,那么返回值可能和实际值不一样了,例如如果两个实型数据分别是1.1和1.0,返回的结果会变成0,这时函数qsort会把它们当成相同的元素。
此时正确的写法应该是return *(double *)p>*(double *)q?1:0;。
参考博客:qsort函数排序各种类型的数据。
【C/C++】qsort函数的使用方法和细节的更多相关文章
- qsort函数以及sort函数使用方法
sort函数的使用方法 做ACM题的时候,排序是一种常常要用到的操作. 假设每次都自己写个冒泡之类的O(n^2)排序,不但程序easy超时,并且浪费宝贵的比赛时间,还非常有可能写错. STL里面 ...
- qsort函数、sort函数【转】
http://blog.163.com/yuhua_kui/blog/static/9679964420142195442766/ 先说明一下:qsort和sort,只能对连续内存的数据进行排序,像链 ...
- C中的qsort函数和C++中的sort函数的理解与使用
一.qsort()函数 原型:_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*)); ...
- qsort函数用法【转】
qsort函数用法 qsort 功 能: 使用快速排序例程进行排序 用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(con ...
- qsort函数用法
qsort函数用法 qsort 功 能: 使用快速排序例程进行排序 用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(co ...
- qsort函数用法(转)
qsort函数用法 qsort 功 能: 使用快速排序例程进行排序 用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(c ...
- C语言qsort函数用法
qsort函数简介 排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等. 看名字都知道快速排序是目前公认的一种比较好的排序算法.因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用. ...
- 关于c语言中qsort函数的一点心得
今天写c时无意间用到了排序,便想着使用c语言标准库中提供的排序函数,即qsort函数(c++stl中提供了sort函数用于排序),首先是介绍qsort函数的一些基本用法(以下内容转自: http:// ...
- qsort函数、sort函数 (精心整理篇)
先说明一下qsort和sort,只能对连续内存的数据进行排序,像链表这样的结构是无法排序的. 首先说一下, qsort qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有 ...
随机推荐
- Entity Framework 6.0 入门系列 第一篇
Entity Framework 6.0 入门系列 第一篇 好几年前接触过一些ef感觉不是很好用,废弃.但是 Entity Framework 6.0是经过几个版本优化过的产物,性能和功能不断完善,开 ...
- 小白学Python(1)——安装与调试,“你好,世界”,“hello,world”
之前从没接触过编程之类的东西,在网上下载个自己需要的软件真实比较麻烦,找了半天总是没有合适的,好不容易找到了,不过那家公司已经倒闭了,软件不更新也运行不了了,于是乎,求人不如求己,自己没事编程吧. 在 ...
- 消息中间件——RabbitMQ(七)高级特性全在这里!(上)
前言 前面我们介绍了RabbitMQ的安装.各大消息中间件的对比.AMQP核心概念.管控台的使用.快速入门RabbitMQ.本章将介绍RabbitMQ的高级特性.分两篇(上/下)进行介绍. 消息如何保 ...
- 原生js实现的一个随机颜色的简单效果
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta na ...
- 三维动画形变算法(Gradient-Based Deformation)
将三角网格上的顶点坐标(x,y,z)看作3个独立的标量场,那么网格上每个三角片都存在3个独立的梯度场.该梯度场是网格的微分属性,相当于网格的特征,在形变过程中随控制点集的移动而变化.那么当用户拖拽网格 ...
- 【乘风破浪】Android系统启动流程整理
前言 对于一个Android应用层开发者来说,了解Android系统的启动流程对理解Android系统有很大的帮助.这其中包含了大量的细节,而且前面很多步骤包含了C/C++实现的native层逻辑,作 ...
- Redis学习总结(一)--Redis入门
Redis 概念 1.Redis 是什么 Redis 是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理. 2.Redis 能干什么 Redis 支持字符串.哈希 ...
- Http请求传json数据中文乱码问题
业务场景:调easyui的dialog打开一个弹窗,传参是用json封装的,而且有中文,然后在极速模式是正常的,在ie11测试发现中文出现乱码了 var params = JSON.stringify ...
- JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)
前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...
- ElasticSearch:组合查询或复合查询
Bool查询 允许在单独的查询中组合任意数量的查询,指定的查询语句表名哪些部分是必须匹配(must).应该匹配(should)或不能匹配(must_not) Bool过滤器 和查询功能一致,但是同等情 ...