C语言qsort函数的使用

来源:互联网 发布:买下跳跃网络要多少钱 编辑:程序博客网 时间:2024/06/05 11:04

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,100sizeof(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,100sizeof(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,100sizeof(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

0 0
原创粉丝点击