C中qsort函数的六类详细使用方法

qsort()是C中的排序函数,其头文件为:#include<stdlib.h> 


1、qsort()----六类qsort排序方法 

qsort函数功能很强大,但如结构体一级排序、二级排序、字符串排序等使用起来较为复杂。

 函数原型: 

void __cdecl qsort (void *base,size_t num,size_t width,int (__cdecl *comp)(const void *,const void*))

输入参数: 

Base:待排序的数组 
num:数组元素的个数(长度) 
width:每一个元素所占存储空间的大小 
comp:用于对数组元素进行比较的函数的指针(需自己定义,决定排列的顺序)
以下是其具体分类及用法(升序排列): 
一、对一维数组排序: 

(Element_type 是一位数组中存放的数据类型,可以是char,int,float,double,ect) 

int comp(const void * a,const void * b) 

        return  *((Element_type*)a)>*((Element_type*)b)?1:-1; 

        int main()

        Element_type list[MAX]; 
        initial(list);//这是对数组list[max]初始化 ,具体需要自己写,直接赋值初始化或者利用memset函数

        qsort(list, sizeof(list),sizeof(Element_type),comp);//调用函数qsort         

        return 0; 


二、对字符串排序: 

int Comp(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的长度 

三、按结构体中某个关键字排序(对结构体一级排序):

 struct Node { 

        double data; 
        int other; 
}s[100]; 

int Comp(const void* a,const void* b)

 { 

     struct node *c=(node *)a;

     struct node *d=(node *)b;

     return  (((c->date)>(d->date))?1:-1);//这里注意不要将强制转换直接写入到return语句中

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

四、按结构体中多个关键字排序(对结构体多级排序)[以二级为例]: 

struct Node 

        int x;         int y; 
}s[100]; 

//按照x从小到大排序,当x相等时按y从大到小排序(这是3跟4的区别) 

int Comp(const void *a,const void *b) 

        struct Node *c=(Node *)a; 

        struct Node *d=(Node *)b;         

if(c->x!=d->x)  

                return c->x-d->x; 

        else  

                return d->y - c->y;

 } 

五、对结构体中字符串进行排序: 

struct Node { 

        int data; 

        char str[100]; 

}s[100]; 

//按照结构体中字符串 str 的字典序排序 

int Comp(const void *p1,const void *p2) 

        return strcmp((*(Node *)p1).str,(*(Node *)p2).str); 

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

六、计算几何中求凸包的 comp  
int cmp(const void *a,const void *B) // 重点 cmp 函数,把除了 1 点外的所有点,旋转
角度排序  
{  
struct point *c=(point *)a;  
struct point *d=(point *)b; 

if( calc(*c,*d,p[1]) < 0) 

return 1;

else if( !calc(*c,*d,p[1]) && dis(c->x,c->y,p[1].x,p[1].y) < dis(d->x,d->y,p[1].x,p[1].y))// 如果在一条直线上,则把远的放在前面  

return 1;  

else 

return -1;  
}

七、对字符串数组进行排序(char *s[])

int main()

{

     scanf("%d",&n);

     for(i=0;i<n;i++)

     {

         s[i]=(char*)malloc(sizeof(char*));

         scanf("%s",s[i]);

     }

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

     for(i=0;i<n;i++) printf("%sn",s[i]);

     return(0);

}

int cmp(const void *a,const void *b)

{

     return (strcmp(*(char**)a,*(char**)b));

}


** 关于快排的一些小问题 **

 

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

 

手工实现QuickSort

#include <stdio.h>
 
int a[100],n,temp;
 
void QuickSort(int h,int t)
{
     if(h>=t) return;
     int mid=(h+t)/2,i=h,j=t,x;
     x=a[mid];
     while(1)
     {
         while(a[i]<x) i++;
         while(a[j]>x) j--;
         if(i>=j) break;
         temp=a[i];
         a[i]=a[j];
         a[j]=temp;
     }
     a[mid]=a[j];
     a[j]=x;
     QuickSort(h,j-1);
     QuickSort(j+1,t);
     return;
}
 
int main()
{
     int i;
     scanf("%d",&n);
     for(i=0;i<n;i++) scanf("%d",&a[i]);
     QuickSort(0,n-1);
     for(i=0;i<n;i++) printf("%d ",a[i]);
 
     return(0);
}

如有疑问,请随时提出,若有出错,请不吝指正!O(∩_∩)O谢谢

你可能感兴趣的:(排序,快速排序,qsort,快排,qsort函数)