qsort函数使用前提:
qsort函数必须是对于连续的内存的数据进行排序,不能对链表进行排序;
qsort:
定义:qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有多个重复值的数组来说,基本快速排序的效率较低,且不稳定)。集成在C语言库函数里面的qsort函数,使用三路划分的方法解决排序这个问题。所谓三路划分,是指把数组划分成小于划分值,等于划分值和大于划分值的三部分。
使用前需要加头文件
#include<stdlib.h>
具体介绍
void __cdecl qsort (void base,size_t num,size_t width,int (__cdecl *comp)(const void ,const void*))
qsort(quicksort)主要根据你给的比较条件给一个快速排序,主要是通过指针移动实现排序功能,排序之后的结果仍然放在原来数组中。
参数意义:
Base:待排序的数组;或者说是需要排序的数组名(也可以理解成开始排序的地址,因为可以写成&s[i],这样的表达式);
num: 数组中待排序元素数量;
width:单个元素的大小(或者说是目标排序中的每一个元素的长度)建议使用sizeof(s[0])这样的表达式;
compare:用于对数组元素进行比较的函数的指针(需要自己定义,用于确定排序的顺序);
compare函数的分析:
返回值必须是int,参数是(const void*a,const void *b),如果是要升序,那么就是如果a比b大,返回一个正值,小则返回负值,相等则为0,降序的话相反;
qsort函数的使用情况:
1.对int类型的数组排序:
int num[100];
int compare(const void *a,const void *b)
{
return *(int *)a - *(int *)b;//升序排序;
//return *(int *)b - *(int *)a;//降序排序;
/*可见,参数列表是两个空指针,现在他要指向你的数组元素,所以要转型变成数组当前的类型,然后取值。升序排序是,若第一个参数指向的“值”大于第二个参数指向的“值”,则返回为正;等于则返回0,若小于,则返回负值。降序排序正好相反;
*/
}
code:
#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);
}
2.char数组的排序(同int)
3.double数组类型的排序(需要注意)
double s[100];
int cmp(const void *a,const void *b)
{
return *(double *)a>*(double*)b?1:-1;
/*返回值为int所以需要注意返回时需要用三目运算符;在对浮点或者double型的一定要用三目运算符,因为如果也使用整型那样的想减的话,如果是两个很接近的数则可能返回一个小数(大于-1,小于1),而cmp的返回值是int型,因此会将这个小数返回0,系统认为是相等,失去了本来存在的大小关系
*/
}
qsort(s,100,sizeof(s[0],cmp);
4.对结构体的一级排序:
struct In{
double data;
int count;
}s[100];
//按照data的值进行排序,
int cmp(const void *a,const void *b)
{
struct In *m = (In *)a;
struct In *n = (In *)b;
return m->data>n->data?1:-1;
/*这里注意不要将强制转换直接写入到return语句中并且注意.和->的区别还是拿屋子作比方:
这儿有一间屋子,你问屋子的主人:“存折在哪儿放着啊?”
主人用手一指床旁边的柜子,说:“床头柜第二个抽屉里面。”
这是 ->
主人打开柜子,把你的手放在了存折上面,说:“这儿呢。”
这是 .(知乎上关于.和->的理解);http://www.360doc.com/content/13/0408/23/6590333_277031379.shtml
*/
qsort(s,100,sizeof(s[0]),cmp);
5.对结构体的二级排序:
struct In{
int x;
int y;
}s[100];
int cmp(const void *a,const void *b)
{
struct In *m = (In *)a;
struct In *n = (In *)b;
if(m->x!=n->x){
return m->x-n->x;
}
else{
return m->y-n->y;
}//x元素相等时才用y排序;
}
qsort(s,100,sizeof(s[0]),cmp);
6.对结构体中的字符串进行排序:
struct In{
int data;
char str[100];
}s[100];
int cmp(const void *a,const void *b){
struct In *m = (In *)a;
struct In *n = (In *)b;
return strcmp(m->str,n->str);
}
qsort(s,100,sizeof(s[0]),cmp);
7.对字符串进行排序
int cmp(const void *a,const void *b)
{
return strcmp((char *)a,(char *)b);
}
int main()
{
char a[MAX1][MAX2];
initial(a);
qsort(a,lenth,sizeof(a[0]),Comp); //lenth 为数组a的长度
}
使用qsort需要注意的:
1.快排是不稳定的,这个不稳定一个表现在其使用的时间是不确定的,最好情况(O(n))和最坏情况(O(n^2))差距太大,我们一般说的O(nlog(n))都是指的是其平均时间.另一个不稳定表现在如果相同的比较元素,可能顺序不一样,假设我们有这样一个序列,3,3,3,但是这三个3是有区别的,我们标记为3a,3b,3c,快排后的结果不一定就是3a,3b,3c这样的排列,所以在某些特定场合我们要用结构体来使其稳定。
元素相同解决办法:
3.快排的比较函数的两个参数必须都是const void *的,这个要特别注意,同时注意对两个指针a,b进行强制转换。
4.快排qsort的第三个参数,那个sizeof,推荐是使用sizeof(s[0])这样,特别是对结构体。
5.如果要对数组进行部分排序,比如对一个s[n]的数组排列其从s[i]开始的m个元素,只需要
在第一个和第二个参数上进行一些修改:qsort(&s[i],m,sizeof(s[i]),cmp);
总结
与http://www.cnblogs.com/ForeverJoker/archive/2013/05/25/qsort-sort.html和http://blog.csdn.net/u014492609/article/details/37761149