c语言qsort函数对结构体的一级排序,排序sort和qsort函数对结构体的二级排序

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

具体介绍 -^^void qsort(void*base, size_tnum, size_twidth, int (__cdecl *compare)int compare(constvoid*elem1,constvoid*elem2) );qsort 即 quicksort主要根据你给的比较条件给一个快速排序主要是通过指针移动实现排序功能。排序之后的结果仍然放在原来数组中。

参数意义如下:

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

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

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

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

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

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

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

q s o rt的使用方法

一、对i nt类型数组排序intnum[100];int cmp(constvoid*a,constvoid*b)

{return*(int*)a- *(int*)b; //升序排序

//return*(int*)b-*(int*)a;//降序排序

/*可见参数列表是两个空指针现在他要去指向你的数组元素。所以转型为你当前的类型然后取值。

升序排列时若第一个参数指针指向的“值”大于第二个参数指针指向的“值”则返回正若第一个参数指针指向的“值”等于第二个参数指针指向的“值”则返回零若第一个参数指针指向的“值”小于第二个参数指针指向的“值”则返回负。

降序排列时则刚好相反。

*/

}qsort(s,n,sizeof(s[0]),cmp);

示例完整函数已在VC6.0上运行通过 

#include

#include

#includeints[10000],n,i;intcmp(constvoid*a,constvoid*b)

{return(*(int*)b-*(int*)a); //实现的是升序排序

}

intmain()

{

//输入想要输入的数的个数scanf("%d",&n);for(i=0;i

}

二、对char类型数组排序同int类型charword[100];intcmp(constvoid*a,constvoid*b)

{

//注意 网上很多版本是“return*(char*)a-*(int*)b; ”

//因为编辑者的不用心盲目copy 以讹传讹传的一直是错的*(int*)b//应该是return*(char*)a-*(char*)b;return*(char*)a-*(char*)b;

}qsort(word,100,sizeof(word[0]),cmp);

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

三、对double类型数组排序特别要注意

double in[100];intcmp(constvoid*a,constvoid*b)

{re t u rn*(d o u b le*)a>*(d o u b le*)b?1: -1;

//返回值的问题显然cmp返回的是一个整型所以避免double返回小数而被丢失用一个判断返回值。

}qsort(in,100,sizeof(in[0]),cmp);

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

/*在这里多嘴一句 "%g"格式输出虽然书上是说系统会自动选择"%f"格式和"%e"格式中长度较短的格式并去掉无意义的0但实际上系统如果选择了"%e"系统会输出比“%e"格式更省一位的格式输出。 此结论来自VC6.0的实际操作 */

四、对结构体一级排序struct In

{doubledata;intother;

}s[100]

//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种参考上面的例子写intcmp(constvoid*a,constvoid*b)

{return(*(In*)a).data>(*(In*)b).data?1: -1;

//注意这条语句在VC6.0环境下运行可能会出错但是并不是语句错了而是你要先Bui ld或者全部重建。总之语句是对的。

//或者你可以将这上面1条语句改成下面这3条语句

//struct In*aa=(In*)a;

//struct In*bb=(In*)b;

//return aa->data>bb->data?1: -1;

}qsort(s,100,sizeof(s[0]),cmp);

五、对结构体二级排序struct In

{intx; //你可以比喻成失败次数inty; //你可以比喻成成功次数

}s[100];

//按照x从小到大排序当x相等时按照y从大到小排序。你可以想象成失败是主要因素的一个问题先比较失败次数少失败次数相同再看成功次数多。intcmp(constvoid*a,constvoid*b)

{struct In*c=(In*)a;struct In*d=(In*)b;if(c->x!=d->x) return c->x-d->x;elsereturnd->y-c->y;

}

qsort(s,100,sizeof(s[0]),cmp);

六、对字符串进行排序struct In

{intdata;charstr[100];

}s[100];

//按照结构体中字符串str的字典顺序排序int cmp(constvoid*a,constvoid*b)

{return strcmp( (*(In*)a)->str, (*(In*)b)->str);

}qsort(s,100,sizeof(s[0]),cmp);

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

再说说s o rt 常用于C++sort使用时得注明 usingnamespace std;或直接打std: :sort()还得加上#include头文件

例

#include

#includeusingnamespacestd;

intmain()

{inta[20];for(int i=0;i<20;++i)cin>>a[i];s o rt(a,a+20); //范围很明显这里是a+20注意这是必要的如果是a+19for(i=0;i<20;i++) //最后一个值a[19]就不会参与排序。cout<

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

最后我们来说说s o rt、 q s o rt的区别s o rt是q s o rt的升级版如果能用s o rt尽量用s o rt使用也比较简单不像q s ort还得自己去写cm p函数只要注明使用的库函数就可以使用参数只有两个如果是普通用法头指针和尾指针默认sort排序后是升序如果想让他降序排列可以使用自己编的cmp函数

#include

#include

usingnamespacestd;intcmp(inta,intb)

{if(ab则为降序,要注意sort()中cmp()的返值只有1和0不像qsort中存在1   e l sereturn 0;

}intmain(){int i;inta[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<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设有如下结构体: ```c struct student{ char name[20]; int age; float score; }; ``` 可以通过以下代码使用 `qsort` 函数结构体数组 `students` 按照分数从高到低进行排序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> struct student{ char name[20]; int age; float score; }; int cmp(const void *a, const void *b); int main() { struct student students[5] = {{"Tom", 20, 86.5}, {"Jerry", 19, 92.0}, {"Alice", 21, 78.5}, {"Bob", 18, 95.0}, {"Ted", 20, 88.5}}; int i; printf("Before sorting:\n"); for(i = 0; i < 5; i++){ printf("%s, %d, %.1f\n", students[i].name, students[i].age, students[i].score); } qsort(students, 5, sizeof(struct student), cmp); printf("\nAfter sorting:\n"); for(i = 0; i < 5; i++){ printf("%s, %d, %.1f\n", students[i].name, students[i].age, students[i].score); } return 0; } int cmp(const void *a, const void *b) { struct student *s1 = (struct student *)a; struct student *s2 = (struct student *)b; if(s1->score < s2->score){ return 1; } else if(s1->score > s2->score){ return -1; } else{ return 0; } } ``` 其中,`qsort` 函数的参数依次为: - 待排序的数组名 `students` - 数组中元素的个数 `5` - 每个元素的大小 `sizeof(struct student)` - 比较函数 `cmp` `cmp` 函数用于定义两个元素之间的大小关系,返回值为负数表示第一个元素比第二个元素小,返回值为正数表示第一个元素比第二个元素大,返回值为零表示两个元素相等。在本例中,`cmp` 函数按照分数从高到低进行比较。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值