【qsort函数实现】
前言:
首先在进行讲解之前,我们先进行对函数的一些相关介绍,方便大家更好的理解它。
目录
- 函数介绍
- 函数实现
函数介绍
第一步:
我们可以先查询知道函数的使用方法:
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
使用qsort()函数的好处就是可以排序任意类型的数据,不像冒泡排序只能排序整形数组;
此函数使用的排序算法通过调用指定的函数来比较元素对,并将指向它们的指针作为参数;
可以看到这个函数有四个参数:
第一个参数指向要排序的数组的第一个对象的指针,转换为 .void*;
第二个参数是数组中元素的个数;
第三个是数组中每个元素的大小(以字节为单位),是无符号整型。size_t;
第四个指向比较两个元素的函数的指针。
具体可以参见:
https://legacy.cplusplus.com/reference/cstdlib/qsort/?kw=qsort
函数实现
第二步:
使用qsort函数对int类型进行排序:
int cmp_int(const void* e1, const void* e2)
{return (*(int*)e1 - *(int*)e2);
}//测试qsort函数排序整型数据
void test()
{int arr[] = { 2,1,3,7,5,9,6,8,0,4 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_int);print(arr, sz);
}
可以看到我们要比较两个整形元素的大小关系,所以我们设计函数cmp_int()函数,指向比较两个元素的函数的指针。
重复调用此函数以比较两个元素。它应遵循以下原型:qsort
int compar (const void* p1, const void* p2);
将两个指针作为参数(都转换为常量 void*)。该函数通过返回(以稳定和传递的方式)来定义元素的顺序:
使用qsort函数对结构体类型进行排序:
struct Stu
{char name[20];int age;
};int cmp_stu_by_name(const void* e1, const void* e2)
{return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);//字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值
}int cmp_stu_by_age(const void* e1, const void* e2)
{return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}//测试qsort排序结构体数据
void test()
{struct Stu s[] = { {"张三", 30}, {"李四", 40}, {"王五", 50} };int sz = sizeof(s) / sizeof(s[0]);//按照名字比较qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);//'按照年龄比较qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
在这里我们按照结构体中的名字和年龄来排序,我们设计函数 cmp_stu_by_name和cmp_stu_by_age来进行实现,首先通过强制类型转化e1,e2为结构体指针,这里要将(S*)e1先用括号括起来,因为箭头的优先级更高。
到此,qsort函数如何实现的我们清楚了,那么我们可以怎么使用呢?接下来我们通过改造冒泡排序把冒泡排序改为可以比较任何类型排序,即用冒泡排序的思想模拟qsort。
首先我们先来实现冒牌函数:
//bubble_sort 函数只能排序整型数据
void bubble_sort(int arr[], int sz)
{int i = 0;//趟数for (i = 0; i < sz - 1; i++){//一趟冒泡排序的过程int j = 0;for (j = 0; j < sz-1-i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1]; arr[j + 1] = tmp;}}}
}
void print(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}void test1()
{//冒泡排序//对整型数据进行排序 - 排序为升序int arr[] = { 2,1,3,7,5,9,6,8,0,4 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);print(arr, sz);
}
我们想要改造,首先就是对我们参数的进行改变,变得一致,函数体中的比较部分我们也提出,相邻的个自比较改造如下:
函数参数部分:
void bubble_sort2(void* base, int sz, int width, int (*cmp)(const void* e1, const void*e2))
比较部分:
if (cmp((char*)base+j*width, (char*)base+(j+1)*width)>0)
//交换
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
cmp的参数是这两个元素的地址,之后在自己所创作的函数中再去强制类型转化为所需类型,第一个元素地址就是base,如何找到之后的呢,首先将其转化为char的指针,其加即就是原地址越过一个字节的地址,这里就需要到了第三个参数int width,代表所占的字节空间数,可以用sizeof直接计算,第一个元素的地+1width就跳到了第二个元素了,后面同理可得(char)base + width * j ,widthj跳过第j个元素的地址,这就代表了第j+1个元素的地址,(char)base + width * (j + 1)代表j+2个元素的地址 ,这样就可以访问到所有元素了,比较完后,if如果大于0.,交换两个元素,所以我们还需要设计一个交换的函数,即如下:
void Swap(char*buf1, char* buf2, int width)
{int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}
我们将两个元素的地址交给Swap(),char类型来接收,但是char只能访问一个字节,接下来我们就需要引入Swap的第三个参数了,width,交换width个字节,及实现了相应的功能。
最后代码如下:
void bubble_sort2(void* base, int sz, int width, int (*cmp)(const void* e1, const void*e2))
{int i = 0;//趟数for (i = 0; i < sz - 1; i++){//一趟冒泡排序的过程int j = 0;for (j = 0; j < sz - 1 - i; j++){if (cmp((char*)base+j*width, (char*)base+(j+1)*width)>0){//交换Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}
}
到此,qsort函数的介绍便结束了,希望大家多多支持!
【qsort函数实现】相关推荐
- c语言标准库低通的qsort函数不适宜所有排序任务的原因
c语言标准库低通的qsort函数不适宜所有排序任务的原因: 第一:它只能用于内存中的数组排序,不能对链表中的数据排序: 第二:因为它是参数化的函数,所以能对各种数据进行操作,也造成它的运行速度比针对单 ...
- C中的qsort函数和C++中的sort函数的理解与使用
一.qsort()函数 原型:_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*)); ...
- 【编码】对qsort函数的稳定排序优化-京东实习笔试编程题(一)-2016.04.08
今晚在做京东的笔试题时,使用了qsort函数,由于排序结果不稳定,导致一直无法ac.后来在待排序的结构体中多加入一个关键字段,较简单的解决了问题. 题目: 生日礼物 Time Limit: 2000/ ...
- C语言程序设计之标准库快速排序qsort函数用法示例
C语言程序设计之标准库快速排序qsort函数,排序效率高,使用方便,太棒了. qsort函数定义如下: #include <stdlib.h>void qsort(void *base, ...
- 总结一下qsort()函数的使用与注意
一.简介 原 型: void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *)); ...
- qsort函数应用大全
七种qsort排序方法 <本文中排序都是采用的从小到大排序> 一.对int类型数组排序 int num[100]; Sample: int cmp ( const void *a , co ...
- qsort()函数详解
一.写在开头 1.1 本节内容 学习C语言中的qsort()函数. 二.qsort() 2.1 函数原型 void qsort(void *base,size_t nmemb,size_t size, ...
- 在c++中qsort()排序函数的使用qsort函数应用大全
七种qsort排序方法 <本文中排序都是采用的从小到大排序> 一.对int类型数组排序 int num[100]; Sample: int cmp ( const void *a , co ...
- qsort函数使用手册
原网址:http://www.maycode.com/index.php/linux/54-linuxdevelop/1386-cpp.html qsort包含在<stdlib.h>头文件 ...
- 【C语言】qsort函数用法(转)
qsort函数用法 qsort 功 能: 使用快速排序例程进行排序 用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(cons ...
最新文章
- 2021年度最有成就感的几件事
- 第四届国际软件自由日在西安邮电学院的发言
- linux服务器运行matlab文件报错
- python的心得体会200字_python_学习心得
- 普通索引和唯一索引,傻傻分不清楚?
- xcode5. 安装cocos2d-x 学习中。。。
- 再来关注一哥们的博客 水木 风雪
- 快速迁移数据中心:华为云数据库SQL Server实践案例技术解析
- 花了25万,还是得不到一模一样的猫!国内首只克隆猫主人发声...
- stringstream常见用法介绍
- 非极大值抑制(Non-Maximum Suppression,NMS)(转)
- Flutter 2019 产品路线图正式公布
- JetBrains(Intellij, pycharm)多行编辑模式
- 离线RSS浏览FeedDemon
- mac brew 启动服务时报错“Bootstrap failed: 5: Input/output error”
- 《大象:thinking in uml 》(第二版) 3章 UML核心元素 4-7节 边界、业务实体、包、分析类
- Android Studio 安装AVD (处理器为AMD)图文详解
- 软件加壳的简易实现方式
- 偏差与方差、L1正则化、L2正则化、dropout正则化、神经网络调优、批标准化Batch Normalization(BN层)、Early Stopping、数据增强
- python分数约分_python分数的四则运算