第一篇

qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有多个重复值的数组来说,基本快速排序的效率较低,且不稳定)。集成在C语言库函数里面的的qsort函数,使用 三 路划分的方法解决排序这个问题。所谓三路划分,是指把数组划分成小于划分值,等于划分值和大于划分值的三个部分。

具体介绍:-^^

voidqsort( void *base, size_t num, size_t width, int (__cdecl *compare )

intcompare (const void *elem1, const void *elem2 ) );

qsort(即,quicksort)主要根据你给的比较条件给一个快速排序,主要是通过指针移动实现排序功能。排序之后的结果仍然放在原来数组中。

参数意义如下:

第一个参数 base 是 需要排序的目标数组名(或者也可以理解成开始排序的地址,因为可以写&s[i]这样的表达式)

第二个参数 num 是 参与排序的目标数组元素个数

第三个参数 width 是单个元素的大小(或者目标数组中每一个元素长度),推荐使用sizeof(s[0])这样的表达式

第四个参数 compare 就是让很多人觉得非常困惑的比较函数啦。

我们来简单讨论compare这个比较函数(写成compare是我的个人喜好,你可以随便写成什么,比如 cmp 什么的,在后面我会一直用cmp做解释)。

典型的compare的定义是int compare(const void *a,constvoid *b);

返回值必须是int,两个参数的类型必须都是const void *,那个a,b是随便写的,个人喜好。假设是对int排序的话,如果是升序,那么就是如果a比b大返回一个正值,小则负值,相等返回0,其他的依次类推,后面有例子来说明对不同的类型如何进行排序。

qsort的使用方法:

一、对int类型数组排序

int num[100];int cmp ( const void *a , const void *b ){return *(int *)a - *(int *)b;  //升序排序//return*(int *)b - *(int *)a; //降序排序/*可见:参数列表是两个空指针,现在他要去指向你的数组元素。所以转型为你当前的类型,然后取值。升序排列时,若第一个参数指针指向的“值”大于第二个参数指针指向的“值”,则返回正;若第一个参数指针指向的“值”等于第二个参数指针指向的“值”,则返回零;若第一个参数指针指向的“值”小于第二个参数指针指向的“值”,则返回负。降序排列时,则刚好相反。*/}qsort(s,n,sizeof(s[0]),cmp);

示例完整函数(已在 VC6.0上运行通过):

#include<stdio.h>#include<string.h>#include<stdlib.h>int s[10000],n,i;int cmp(const void *a,const void *b){return(*(int*)b-*(int *)a);  //实现的是升序排序}int main(){//输入想要输入的数的个数scanf("%d",&n);for(i=0;i<n;i++)scanf("%d",&s[i]);qsort(s,n,sizeof(s[0]),cmp);for(i=0;i<n;i++)printf("%d",s[i]);return(0);}

二、对char类型数组排序(同int类型)

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

//附,可能getchar(); 会派上用场

三、对double类型数组排序(特别要注意)

double in[100];int cmp( const void *a , const void *b ){return*(double *)a > *(double *)b ? 1 : -1;//返回值的问题,显然cmp返回的是一个整型,所以避免double返回小数而被丢失,用一个判断返回值。}qsort(in,100,sizeof(in[0]),cmp);

//附:排序结果的输出,一般建议用 “ %g ” 格式

四、对结构体一级排序

struct In{double data;int other;}s[100]int cmp( const void *a ,const void *b){return(*(In *)a).data > (*(In *)b).data ? 1 : -1;//或者你可以将这上面1条语句改成下面这3条语句//structIn *aa = (In *)a;//structIn *bb = (In *)b;//returnaa->data > bb->data ? 1 : -1;}qsort(s,100,sizeof(s[0]),cmp);

五、对结构体二级排序

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;else return d->y - c->y;}qsort(s,100,sizeof(s[0]),cmp);

六、对字符串进行排序

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(s[0]),cmp);

注意!qsort 中的 cmp 得自己写 。

再说说 sort (常用于 C++ )

sort使用时得注明:using namespace std; 或直接打 std::sort() 还得加上 #include 头文件

例:

#include<iostream>#include<algorithm>usingnamespace std;int main(){int a[20];for(int i=0;i<20;++i)cin>>a[i];sort(a,a+20);             //范围,很明显这里是a+20 注意,这是必要的,如果是a+19for(i=0;i<20;i++)        //最后一个值a[19]就不会参与排序。cout<<a[i]<<endl;return0;}

std::sort是一个改进版的qsort. std::sort函数优于qsort的一些特点:对大数组采取9项取样,更完全的三路划分算法,更细致的对不同数组大小采用不同方法排序。

最后,我们来说说sort、qsort的区别:

sort是qsort的升级版,如果能用sort尽量用sort,使用也比较简单,不像qsort还得自己去写 cmp 函数,只要注明 使用的库函数就可以使用,参数只有两个(如果是普通用法)头指针和尾指针;

默认sort排序后是升序,如果想让他降序排列,可以使用自己编的cmp函数

#include<iostream>#include<algorithm>usingnamespace std;int cmp(int a,int b){if(a<b)return 1; //升序排列,如果改为 a >b,则为降序,要注意sort()中cmp()的返值只有1和0,不像qsort中存在-1!!!!elsereturn 0;}int main(){int i;int a[20];for(int i=0;i<5;++i)cin>>a[i];sort(a,a+5,cmp);          //范围,很明显这里是a+5 注意,这是必要的,如果是a+4最后一个值a[4]就不会参与排序。for(i=0;i<5;i++)      cout<<a[i]<<endl;system("pause");return 0;}

对二维数组的排序:

#include<iostream>#include<algorithm>#include<ctime>usingnamespace std;bool cmp(int *p,int *q){if(p[0]==q[0]){if(p[1]==q[1]){return p[2]<q[2];}else return p[1]<q[1];}else return p[0]<q[0];}int main(){srand(time(0));int i;int **a=new int*[1000];for(i=0;i<1000;++i){a[i]=newint[3];a[i][0]=rand()%1000;a[i][1]=rand()%1000;a[i][2]=rand()%1000;//printf("%d\t%d\t%d\n",a[i][0],a[i][1],a[i][2]);}sort(a,a+1000,cmp);/*cout<<"Aftersort"<<endl;for(i=0;i<1000;++i){printf("%d\t%d\t%d\n",a[i][0],a[i][1],a[i][2]);}*/return 0;}

第二篇

C语言标准库函数 qsort详解
qsort包含在<stdlib.h>头文件中,此函数根据你给的比较条件进行快速排序,通过指针移动实现排序。排序之后的结果仍然放在原数组中。使用qsort函数必须自己写一个比较函数。

函数原型:

void qsort ( void * base, size_tnum, size_t size, int ( * comparator ) ( const void *, const void * ) );

指向任意数据类型的指针都可以转换为void*类型

用法以及参数说明:
Sortsthe num elements of the array pointed by base, each element size bytes long,using the comparator function to determine the order.

   Thesorting algorithm used by this function compares pairs of values by calling thespecified comparator function with two pointers to elements of the array.Thefunction does not return any value, but modifies the content of the arraypointed by base reordering its elements to the newly sorted order.basePointer to the first element of the array to be sorted.(数组起始地址)numNumber of elements in the array pointed by base.(数组元素个数)sizeSize in bytes of each element in the array.(每一个元素的大小)comparatorFunction that compares two elements.(函数指针,指向比较函数)

1、The function must accept two parameters that are pointers to elements,type-casted as void*. These parameters should be cast back to some data typeand be compared.

2、The return value of this function should represent whether elem1 isconsidered less than, equal to, or greater than elem2 by returning,respectively, a negative value, zero or a positive value.

Return Value none (无返回值)

   给你们的C++帮助文档上面的语法及定义是:

语法:

#include <stdlib.h>

void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );

功能: 对buf 指向的数据(包含num 项,每项的大小为size)进行快速排序。如果函数compare 的第一个参数小于第二个参数,返回负值;如果等于返回零值;如果大于返回正值。函数对buf 指向的数据按升序排序。

关键比较函数

一、对int类型数组排序

int num[100];int cmp ( const void *a , const void *b )
{return *(int *)a - *(int *)b;
}qsort对int类型的数组排序#include<iostream>using namespace std;int num[100];int cmp(const void* a,const void* b){return*(int*)a - *(int*)b;}int main(){intn,i;cout<<"请输入数组大小:"<<endl;cin>>n;for(i=0;i<n;i++)///初始化cin>>num[i];qsort(num,n,sizeof(num[0]),cmp);for(i=0;i<n;i++){if(i==n-1)cout<<num[i]<<endl;elsecout<<num[i]<<" ";}return0;}

二、对char类型数组排序(同int类型)

char word[100];int cmp( const void *a , const void *b )
{return *(char *)a - *(char *)b;
}qsort(word,100,sizeof(word[0]),cmp);注:按ASCII码排序,类似intqsort对char类型的数组排序#include<iostream>using namespace std;char num[100];int cmp(const void* a,const void* b){return*(char*)a - *(char*)b;}int main(){intn,i;cout<<"请输入数组大小:"<<endl;cin>>n;for(i=0;i<n;i++)///初始化cin>>num[i];qsort(num,n,sizeof(num[0]),cmp);for(i=0;i<n;i++){if(i==n-1)cout<<num[i]<<endl;elsecout<<num[i]<<" ";}return0;}

三、对double类型数组排序

double in[100];int cmp( const void *a , const void *b )
{return *(double *)a > *(double*)b ? 1 : -1;
}qsort(in,100,sizeof(in[0]),cmp);qsort对double类型的数组排序#include<iostream>using namespace std;double num[100];int cmp(const void* a,const void* b){return*(double*)a - *(double*)b;}int main(){intn,i;cout<<"请输入数组大小:"<<endl;cin>>n;for(i=0;i<n;i++)///初始化cin>>num[i];qsort(num,n,sizeof(num[0]),cmp);for(i=0;i<n;i++){if(i==n-1)cout<<num[i]<<endl;elsecout<<num[i]<<" ";}return 0;}四、对结构体一级排序
struct Sample{doubledata;intother;}s[100];//按照data的值从小到大将结构体排序int cmp( const void *a ,const void *b){return(*(Sample *)a).data > (*(Sample *)b).data ? 1 : -1;}qsort(s,100,sizeof(s[0]),cmp);程序qsort对结构类型的数组一级排序#include<iostream>using namespace std;struct Sample{intdata;charother;};Sample num[100];///结构数组int cmp(const void* a,const void* b){return((Sample*)a)->data - ((Sample*)b)->data;//return(*(Sample*)a).data - (*(Sample*)b).data;也行的,一个是解引用,一个是直接指针指向}int main(){intn,i;cout<<"请输入数组大小:"<<endl;cin>>n;for(i=0;i<n;i++)///初始化cin>>num[i].data>>num[i].other;qsort(num,n,sizeof(num[0]),cmp);for(i=0;i<n;i++){if(i==n-1)cout<<num[i].data<<" "<<num[i].other<<endl;elsecout<<num[i].data<<" "<<num[i].other<<" ";}return0;}五、对结构体二级排序struct Sample{int x;int y;}s[100];//按照x从小到大排序,当x相等时按照y从大到小排序int cmp( const void *a , const void *b ){structSample *c = (Sample *)a;structSample *d = (Sample *)b;if(c->x!= d->x)returnc->x - d->x;elsereturn d->y - c->y;}qsort(s,100,sizeof(s[0]),cmp);qsort对结构类型的数组二级排序#include<iostream>using namespace std;struct Sample{intdata;charother;};Sample num[100];///结构数组int cmp(const void* a,const void* b){Sample *c = (Sample*)a;Sample *d = (Sample*)b;if(c->data== d->data)returnc->other - d->other;如果结构体中的data相等则执行第二级排序elsereturnc->data - d->data;}int main(){intn,i;cout<<"请输入数组大小:"<<endl;cin>>n;for(i=0;i<n;i++)///初始化cin>>num[i].data>>num[i].other;qsort(num,n,sizeof(num[0]),cmp);for(i=0;i<n;i++){if(i==n-1)cout<<num[i].data<<" "<<num[i].other<<endl;elsecout<<num[i].data<<" "<<num[i].other<<" ";}return0;}

六、对字符串进行排序

struct Sample{intdata;charstr[100];}s[100];//按照结构体中字符串str的字典顺序排序int cmp ( const void *a , const void *b ){returnstrcmp( (*(Sample *)a)->str , (*(Sample *)b)->str );}qsort(s,100,sizeof(s[0]),cmp);对字符串进行排序#include<iostream>using namespace std;struct Sample{charch[100];};Sample num[100];///结构数组int cmp(const void* a,const void* b){returnstrcmp( ((Sample*)a)->ch,((Sample*)b)->ch );}int main(){intn,i;cout<<"请输入数组大小:"<<endl;cin>>n;for(i=0;i<n;i++)///初始化cin>>num[i].ch;qsort(num,n,sizeof(num[0]),cmp);for(i=0;i<n;i++){if(i==n-1)cout<<num[i].ch<<endl;elsecout<<num[i].ch<<" ";}return0;}

附加一个完整点的代码,对字符串二维数组排序:

#include <stdio.h>#include <stdlib.h>#include <string.h>char s[2001][1001];int cmp(const void *a, const void *b){returnstrcmp((char *)a,(char*)b);}int main(){inti,n;scanf("%d",&n);getchar();for(i=0;i<n;i++)gets(s[i]);qsort(s,n,1001*sizeof(char),cmp);for(i=0;i<n;i++)puts(s[i]);return0;}

Sort()函数类似,不再一步一步举例,可以自学了
2、sort()
sort 对给定区间所有元素进行排序

stable_sort 对给定区间所有元素进行稳定排序

partial_sort 对给定区间所有元素部分排序

partial_sort_copy 对给定区间复制并排序

nth_element 找出给定区间的某个位置对应的元素

is_sorted 判断一个区间是否已经排好序

partition 使得符合某个条件的元素放在前面

stable_partition 相对稳定的使得符合某个条件的元素放在前面

语法描述为:

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

i

nt _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按升序排序,说到这里可能就有人会问怎么样用它降序排列呢?这就是下一个讨论的内容。

(2)sort(begin,end,compare)

一种是自己编写一个比较函数来实现,接着调用三个参数的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[]){inta[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(){inta[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、not_equal_to、greater、greater_equal、less、less_equal。对于这个问题来说,greater和less就足够了,直接拿过来用:

升序:sort(begin,end,less());

降序:sort(begin,end,greater()).

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

C语言qsort解析相关推荐

  1. C语言qsort函数对二维数组排序的不同情况

    内置排序函数--qsort函数 函数说明: 下面博主讲的很清楚,不多介绍. C语言:qsort()解析 对二维数组: 上文博主提到了对二维数组排序时compare函数的写法,但在具体实践中,我们会发现 ...

  2. 【c语言】C语言配置文件解析库——iniparser

    转载自:http://blog.csdn.net/u011192270/article/details/49339071 C语言配置文件解析库--iniparser 前言:在对项目的优化时,发现Lin ...

  3. C语言配置文件解析库——iniparser

    C语言配置文件解析库--iniparser 1. 1.1前言:在对项目的优化时,发现Linux下没有专门的供给C语言使用的配置文件函数,于是搜索到了iniparser库,可以像那些面向对象语言一样,使 ...

  4. c语言自定义函数程序设计,ch3自定义函数设计 C语言 《解析C程序设计》.ppt

    ch3自定义函数设计 C语言 <解析C程序设计> 全局变量--外部变量 在函数外定义的变量 有效范围:从定义变量的位置开始到本源文件结束,及有extern声明的其它源文件 存储类型:缺省e ...

  5. c语言高函数正确形式,计算机二级C语言考点解析:函数

    小编所收集到的相关计算机二级C语言考点解析:函数的资料 大家要认真阅读哦! 一.库函数的正确调用 1.C语言提供了丰富的库函数,包括常用数学函数.对字符和字符串处理函数.输入输出处理函数等.在调用库函 ...

  6. 论文浅尝 | 面向多语言语义解析的神经网络框架

    论文笔记整理:杜昕昱,东南大学本科生. 来源:ACL2017 链接:https://aclweb.org/anthology/P17-2007 论文训练了一个多语言模型,将现有的Seq2Tree模型扩 ...

  7. C语言 qsort的用法 模拟EXCEL排序

    C语言 qsort的用法 模拟EXCEL排序 题目 Excel可以对一组记录按任意指定列排序.现请编写程序实现类似的功能. 输入 输入的第一行包含两个正整数N(<= 10^5)和C,其中N是记录 ...

  8. 计算机二级c语言考点解析,2017年计算机二级C语言考点解析

    2017年计算机二级C语言考点解析 C语言是一个有结构化程序设计.具有变量作用域(variable scope)以及递归功能的过程式语言.下面是小编整理的关于计算机二级C语言考点解析,希望大家认真阅读 ...

  9. 直击招聘程序员面试笔试C语言深度解析,直击招聘 程序员面试笔试C++语言深度解析(直击招聘) pdf epub mobi txt 下载...

    直击招聘 程序员面试笔试C++语言深度解析(直击招聘) pdf epub mobi txt 下载 图书介绍 ☆☆☆☆☆ 李春葆,李筱驰 著 下载链接在页面底部 发表于2021-05-18 类似图书 点 ...

最新文章

  1. linux环境上c++ boost安装boost_1_67_0.tar
  2. excel 如何快速实现绝对引用
  3. Springboot消除switch-case方法
  4. 名企进名校精选IT人 07年毕业生就业看好
  5. 启动tomcat出现too many connections的原因及解决方法
  6. 五种基于RGB色彩空间统计的皮肤检测算法
  7. Word打开后出现乱码
  8. Introduction to 3D Game Programming with Directx12系列小结
  9. 经纬财富:新乡怎么炒白银能挣到钱?
  10. 用计算机怎么谈黑人团队,光遇黑人抬棺乐谱怎么弹奏 计算机演奏乐谱16
  11. 爱快路由器wifi短信验证上网怎样配置?wifi身份认证方案
  12. 【机器学习】Adaboost
  13. 鸿蒙开发|呼吸训练实战项目(一)
  14. TF-IDF算法类毕业论文文献有哪些?
  15. 统计字符串中每个字符的出现字数
  16. 求含n个元素的集合的幂集
  17. 【信号处理】一种热电偶信号处理算法
  18. NetworkStream
  19. 我的眼睛为什么不近视--我的习惯是怎么样的?
  20. 武汉速达软件测试培训,水运工工程水深测量培训_WGZ.ppt

热门文章

  1. Mahout之——Mahout推荐算法API详解
  2. 神舟十二号“飞天”,盘点背后的“测试秘密”
  3. 511遇见易语言数组加入成员
  4. python画指数函数图像_Python3.0科学计算学习之绘图(一
  5. 友善串口助手与VSPD模拟串口传输信息
  6. 后处理之TCL语言教程
  7. java 如何实现单链表中的头插法
  8. 如何减轻 Smurf 攻击?
  9. 大学生课程设计 ------ Java Web课程设计(图书馆管理系统02)
  10. 国产之路:复旦微调试笔记3:环境配置