C语言qsort()函数的使用

qsort()函数是 C 库中实现的快速排序算法,包含在 stdlib.h 头文件中,其时间复杂度为 O(nlogn)。函数原型如下:

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

此函数需要四个参数。

第一个参数是需要排序的数组的基地址,因为是 void * 类型,所以此函数可以给任何类型的数组进行排序;

第二个参数是待排序的数量(size_t 是一种特别的数据类型,可以近似理解为 int 型);

第三个是单个数组元素的大小,即字节数,例如 int 型就是 4 或者 sizeof(int) (sizeof 的返回值类型就是 sizeof),char 型就是 1 或者

sizeof(char)。因为为了适用于各种数据结构,第一个参数将指向数组的指针强转成了 void * 类型,也即此时函数并不知道将要进行排序的数组内存储的是什么元素,因此我们需要显式地告诉它单个元素所占的长度;

第四个参数是一个指向函数的指针,其作用是规定排序的规则,即按照什么样的方式进行排序。

下面我们对一个整型数组排序为例:

#include<stdio.h>
#include<stdlib.h> //比较函数原型
int mycmp(const void* p1, const void* p2); int main() { int num[10] = {32, -4, 89, 232, 2, 12, -32, 0, -4, 89}; qsort(num, 10, sizeof(int), mycmp); for(int i=0; i<10; i++)
printf("%d ", num[i]); printf("\n");
return 0;
} //比较函数
int mycmp(const void* p1, const void* p2){
const int * a = (const int *) p1;
const int * b = (const int *) p2; int value = 0; if(*a < *b)
value = -1;
else if(*a == *b)
value = 0;
else value = 1; return value;
}

运行结果如下所示:

使用 qsort 最重要的是比较函数的编写。

首先,qsort 函数的原型中已经对此元素的原型有了明确的规定:int (*compar)(const void *, const void *) ,需要传入指向两个元素的指针。

与上文增加第三个参数的原因相同,比较函数的参数指针是 void * 类型,这个参数同样不知道元素实际的大小,因此我们需要进行类型的强转,转换成元素实际类型对应的指针,例如上文中为了给一个 int 型数组排序:

const int * a = (const int *) p1;
const int * b = (const int *) p2;

然后,两个元素之间的比较结果无非 > 、= 、< ,我们要给希望成立的结果返回 1,例如:如果希望从小到大排列,则 *a < *b 成立时返回 1;如果希望从大到小排列,则 *a > *b 返回 1,相应的 *a == *b 返回 0,*a < *b 返回 -1.

因此如果将上述程序的 1 和 -1 颠倒位置,结果就会变成降序排列:

因为可以任意编写比较函数,当比较具有优先级时我们也可以从容解决。

例如:

定义了这样一个表示时间的结构体:

struct Time {
int hour;
int min;
int sec;
};

如果对此类型的数组元素进行升序排列,那么比较函数应该为:

int mycomp(const void * p1, const void * p2){
const Time * a = (const Time *) p1;
const Time * b = (const Time *) p2; int value = 0; if(a->hour > b->hour)
value = 1;
else if(a->hour < b->hour)
value = -1; else{
if(a->min > b->min)
value = 1;
else if(a->min < b->min)
value = -1;
else{
if(a->sec > b->sec)
value = 1;
else if(a->sec < b->sec)
value = -1;
else value = 0;
}
} return value;
}

C语言qsort()函数的使用的更多相关文章

  1. C语言qsort函数用法

    qsort函数简介 排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等. 看名字都知道快速排序是目前公认的一种比较好的排序算法.因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用. ...

  2. CGO封装C语言qsort函数

    封装qsort函数 package qsort /* #include <stdlib.h> typedef int (*qsort_cmp_func_t) (const void* a, ...

  3. C语言qsort函数算法性能测试

    对于该算法的复杂性.一个直接的方法是测量的一定量的算法级数据的执行时间的感知. 随着C语言提供qsort对于示例.随着100一万次的数据,以测试其计算量.感知O(nlg(n))时间成本: C码如下面: ...

  4. C语言qsort()函数的实现

    #include <stdio.h> void qsort(void * base, int num, int width, int (*comp)(const void *, const ...

  5. qsort函数、sort函数【转】

    http://blog.163.com/yuhua_kui/blog/static/9679964420142195442766/ 先说明一下:qsort和sort,只能对连续内存的数据进行排序,像链 ...

  6. qsort函数、sort函数 (精心整理篇)

    先说明一下qsort和sort,只能对连续内存的数据进行排序,像链表这样的结构是无法排序的. 首先说一下, qsort qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有 ...

  7. 使用C语言中qsort()函数对浮点型数组无法成功排序的问题

    一 写在开头 1.1 本节内容 本节主要内容是有关C语言中qsort()函数的探讨. 二 问题和相应解决方法 qsort()是C标准库中的一个通用的排序函数.它既能对整型数据进行排序也能对浮点型数据进 ...

  8. qsort函数、sort函数

    先说明一下qsort和sort,只能对连续内存的数据进行排序,像链表这样的结构是无法排序的. 首先说一下, qsort qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有 ...

  9. c语言中qsort函数的使用、编程中的一些错误

    qsort()函数: 功能:相当于c++sort,具有快排的功能,复杂度的话nlog(n)注:C中的qsort()采用的是快排算法,C++的sort()则是改进的快排算法.两者的时间复杂度都是nlog ...

随机推荐

  1. 三张图秒懂Redis集群设计原理

    转载Redis Cluster原理 转载https://blog.csdn.net/yejingtao703/article/details/78484151 redis集群部署方式: 单机 主从 r ...

  2. Superset SSO改造和自定义宏命令

    目录 背景 关于Superset 需要解决的问题 定制化改造 准备环境 改造OAuth SSO 安装依赖 配置SSO 添加自定义的SecurityManager 运行一下吧 自定义宏命令 开启配置 添 ...

  3. golang中的结构体工厂

    1. main包 package main import ( "day01/utils" "fmt" ) //type File struct { // fd ...

  4. IoC容器(底层原理)

    IoC(概念和原理) 1,什么是IoC (1)控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理 (2)使用IoC目的:为了降低耦合度 (3)做入门案例就是IoC实现 2,IoC底层原 ...

  5. cnpm安装教程

    安装cnpm,输入以下命令: sudo npm install -g cnpm --registry=https://registry.npm.taobao.org 输入cnpm -v ,检测是否正常 ...

  6. 使用Xamarin开发移动应用示例——数独游戏(二)创建游戏界面

    在本系列第一部分,我们创建了程序框架,现在我们创建游戏的界面,项目代码可以从Github下载:https://github.com/zhenl/ZL.Shudu .代码随项目进度更新. 首先在View ...

  7. Kindle连接移动的 Wi-Fi 时要求进行网页浏览器登陆怎么办?

    在电脑上新建一个新文件,名为"WIFI_NO_NET_PROBE",同时把后缀名删掉,让它变成一个无格式文件.Kindle 连接电脑,把新建的文件放进Kindle的根目录,断开Ki ...

  8. 配置Nginx使用Active Directory 做认证

    配置Nginx使用AD做认证 nginx.conf 配置 http { ldap_server ldap { url ldap://xxx:389/DC=test,DC=com?sAMAccountN ...

  9. SIFT,SuperPoint在图像特征提取上的对比实验

    SIFT,SuperPoint都具有提取图片特征点,并且输出特征描述子的特性,本篇文章从特征点的提取数量,特征点的正确匹配数量来探索一下二者的优劣. 视角变化较大的情况下 原图1 原图2 SuperP ...

  10. jstl split 分割字符串?

    1. 在已经获得数据的前提下,对数据进行分割,分割后的结果是一个数组,可以通过数组获得我们需要的数据 2. value 是获得值 需要${} 的方式获取, var 是设置变量. var = " ...