qsort用法(qsort用法是什么)

本文目录
- qsort用法是什么
- 很奇怪 用qsort进行简单的排序,但是有些地方不懂 如下面的那样
- 关于c语言中qsort函数的用法
- c语言,关于qsort的使用,如何将17-20行的冒泡排序用qsort排
- c++中的标准库函数qsort怎么用有什么作用
- C++中qsort怎么用
- 谁能全面讲解下qsort函数,参数,使用方法,具体作用等等
qsort用法是什么
void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
这个是qsort的原型
base是要被排序的数据的起始位置
num是要被排序的元素的个数
size是一个元素的大小,单位是字节
comparator 是一个函数,原型是 int comparator ( const void * a, const void * b)
这个函数取两个元素的地址a和b, 如果a指向的元素比b小, 函数返回负整数
如果a比b大, 返回正整数
如果a和b相等, 返回0
很奇怪 用qsort进行简单的排序,但是有些地方不懂 如下面的那样
这个问题很明显么。。。。
首先,s 是全局变量,会被初始化。s.num 都是 0 。
【从大到小的排序】:
因为:for(i=1;i《=n;i++) scanf(“%d“,&s[i].num); 是从 s 开始存储的,
【第一次】输入5 1 4 3 2 5 ,那么:
s=0(初始值,不是输入值),
s=1,
s=4,
s=3,
s=2,
s=5;
【第一次】调用,qsort(s,n+1,sizeof(node),cmp);
其实是对【从首地址 s开始】的【 n+1 个】大小为【sizeof(node)】的元素排序的,两个元素的【比较法则是cmp】。可以看到,参与排序的元素是 s~s ,一共 6 个元素。
【第一次】排序结果是:
s=5,
s=4,
s=3,
s=2,
s=1,
s=0;
输出是从第 1 个元素开始(不是第 0 个元素)开始的,因此,
【第一次】输出:4 3 2 1 0 ,不是期望的输出结果。注意输出最后一个 0 是原来的 s ,而输入的 5 是现在的 s,没有被输出!
【第二次】输入5 1 4 3 2 5 ,那么:
s=5(上次排序后遗留的结果,不是输入值),
s=1,
s=4,
s=3,
s=2,
s=5;
【第二次】排序结果是:
s=5,(不确定是哪个 5)
s=5,(不确定是哪个 5)
s=4,
s=3,
s=2,
s=1;
输出是从第 1 个元素开始(不是第 0 个元素)开始的,因此,
【第二次】输出:5 4 3 2 1 ,是期望的输出结果。但这只是偶然!
如果你输入:
5 1 4 3 2 5
5 1 4 3 2 6
5 1 4 3 2 7
5 1 4 3 2 8
5 1 4 3 2 9
...
你会发现,输出都是:5 4 3 2 1 !
【从小到大的排序】:
很明显,这个时候,你输入的数字大于 0 , 那么
s = 0 , (初始值,不是输入值),
s 的值 0 永远不会在调用 qsort 函数中移动位置,它永远停留在原来的位置上!可以当做不存在。
但是,当你输入小于 0 的数字,就会出现问题!
比如你输入: 2 -1 -2
你会发现输出是:-2 0 , 而不是 -1 -2
上面的问题是 qsort 没有写正确的原因!
正确的 qsort 写法是:qsort(s+1,n,sizeof(node),cmp);
关于c语言中qsort函数的用法
引自 http://hi.baidu.com/sysucs/blog/item/4f9962f422d2c2ddf2d385fd.html qsort,包含在stdlib.h头文件里,函数一共四个参数,没返回值.一个典型的qsort的写法如下
qsort(s,n,sizeof(s),cmp);
其中第一个参数是参与排序的数组名(或者也可以理解成开始排序的地址,因为可以写&s[i]
这样的表达式,这个问题下面有说明); 第二个参数是参与排序的元素个数; 第三个三数是
单个元素的大小,推荐使用sizeof(s)这样的表达式,下面也有说明 :) ;第四个参数就是
很多人觉得非常困惑的比较函数啦,关于这个函数,还要说的比较麻烦...
我们来讨论cmp这个比较函数(写成cmp是我的个人喜好,你可以随便写成什么,比如qcmp什么
的).典型的cmp的定义是
int cmp(const void *a,const void *b);
返回值必须是int,两个参数的类型必须都是const void *,那个a,b是我随便写的,个人喜好.
假设是对int排序的话,如果是升序,那么就是如果a比b大返回一个正值,小则负值,相等返回
0,其他的依次类推,后面有例子来说明对不同的类型如何进行排序.
在函数体内要对a,b进行强制类型转换后才能得到正确的返回值,不同的类型有不同的处理
方法.具体情况请参考后面的例子.
/*----------------------------------------------------------------------------*/
** 关于快排的一些小问题 **
1.快排是不稳定的,这个不稳定一个表现在其使用的时间是不确定的,最好情况(O(n))和最
坏情况(O(n^2))差距太大,我们一般说的O(nlog(n))都是指的是其平均时间.
2.快排是不稳定的,这个不稳定表现在如果相同的比较元素,可能顺序不一样,假设我们有
这样一个序列,3,3,3,但是这三个3是有区别的,我们标记为3a,3b,3c,快排后的结果不一定
就是3a,3b,3c这样的排列,所以在某些特定场合我们要用结构体来使其稳定(No.6的例子就
是说明这个问题的)
3.快排的比较函数的两个参数必须都是const void *的,这个要特别注意,写a和b只是我的
个人喜好,写成cmp也只是我的个人喜好.推荐在cmp里面重新定义两个指针来强制类型转换,
特别是在对结构体进行排序的时候
4.快排qsort的第三个参数,那个sizeof,推荐是使用sizeof(s)这样,特别是对结构体,
往往自己定义2*sizeof(int)这样的会出问题,用sizeof(s[0)既方便又保险
5.如果要对数组进行部分排序,比如对一个s[n]的数组排列其从s[i]开始的m个元素,只需要
在第一个和第二个参数上进行一些修改:qsort(&s[i],m,sizeof(s[i]),cmp);
/*----------------------------------------------------------------------------*/
** 标程,举例说明 **
No.1.手工实现QuickSort
#include 《stdio.h》
int a,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);
}
No.2.最常见的,对int数组排序
#include 《stdio.h》
#include 《string.h》
#include 《stdlib.h》
int s,n,i;
int cmp(const void *a, const void *b)
{
return(*(int *)a-*(int *)b);
}
int main()
{
scanf(“%d“,&n);
for(i=0;i《n;i++) scanf(“%d“,&s[i]);
qsort(s,n,sizeof(s),cmp);
for(i=0;i《n;i++) printf(“%d “,s[i]);
return(0);
}
No.3.对double型数组排序,原理同int
这里做个注释,本来是因为要判断如果a==b返回0的,但是严格来说,两个double数是不可能相等的,只能说fabs(a-b)《1e-20之类的这样来判断,所以这里只返回了1和-1
#include 《stdio.h》
#include 《stdlib.h》
double s;
int i,n;
int cmp(const void * a, const void * b)
{
return((*(double*)a-*(double*)b》0)?1:-1);
}
int main()
{
scanf(“%d“,&n);
for(i=0;i《n;i++) scanf(“%lf“,&s[i]);
qsort(s,n,sizeof(s),cmp);
for(i=0;i《n;i++) printf(“%lf “,s[i]);
return(0);
}
No.4.对一个字符数组排序.原理同int
#include 《stdio.h》
#include 《string.h》
#include 《stdlib.h》
char s,i,n;
int cmp(const void *a,const void *b)
{
return(*(char *)a-*(char *)b);
}
int main()
{
scanf(“%s“,s);
n=strlen(s);
qsort(s,n,sizeof(s),cmp);
printf(“%s“,s);
return(0);
}
No.5.对结构体排序
注释一下.很多时候我们都会对结构体排序,比如校赛预选赛的那个樱花,一般这个时候都在
cmp函数里面先强制转换了类型,不要在return里面转,我也说不清为什么,但是这样程序会
更清晰,并且绝对是没错的. 这里同样请注意double返回0的问题
#include 《stdio.h》
#include 《stdlib.h》
struct node
{
double date1;
int no;
} s;
int i,n;
int cmp(const void *a,const void *b)
{
struct node *aa=(node *)a;
struct node *bb=(node *)b;
return(((aa-》date1)》(bb-》date1))?1:-1);
}
int main()
{
scanf(“%d“,&n);
for(i=0;i《n;i++)
{
s[i].no=i+1;
scanf(“%lf“,&s[i].date1);
}
qsort(s,n,sizeof(s),cmp);
for(i=0;i《n;i++) printf(“%d %lf\n“,s[i].no,s[i].date1);
return(0);
}
No.6.对结构体排序.加入no来使其稳定(即data值相等的情况下按原来的顺序排)
#include 《stdio.h》
#include 《stdlib.h》
struct node
{
double date1;
int no;
} s;
int i,n;
int cmp(const void *a,const void *b)
{
struct node *aa=(node *)a;
struct node *bb=(node *)b;
if(aa-》date1!=bb-》date1)
return(((aa-》date1)》(bb-》date1))?1:-1);
else
return((aa-》no)-(bb-》no));
}
int main()
{
scanf(“%d“,&n);
for(i=0;i《n;i++)
{
s[i].no=i+1;
scanf(“%lf“,&s[i].date1);
}
qsort(s,n,sizeof(s),cmp);
for(i=0;i《n;i++) printf(“%d %lf\n“,s[i].no,s[i].date1);
return(0);
}
No.7.对字符串数组的排序(char s型)
#include 《stdio.h》
#include 《string.h》
#include 《stdlib.h》
char s;
int i,n;
int cmp(const void *a,const void *b)
{
return(strcmp((char*)a,(char*)b));
}
int main()
{
scanf(“%d“,&n);
for(i=0;i《n;i++) scanf(“%s“,s[i]);
qsort(s,n,sizeof(s),cmp);
for(i=0;i《n;i++) printf(“%s\n“,s[i]);
return(0);
}
No.8.对字符串数组排序(char *s型)
#include 《stdio.h》
#include 《string.h》
#include 《stdlib.h》
char *s;
int i,n;
int cmp(const void *a,const void *b)
{
return(strcmp(*(char**)a,*(char**)b));
}
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),cmp);
for(i=0;i《n;i++) printf(“%s\n“,s[i]);
return(0);
}
c语言,关于qsort的使用,如何将17-20行的冒泡排序用qsort排
试想一下,如果让你自己设计qsort函数,需要些什么东西,首地址要有吧,总共有几个元素要有吧,每个元素占多大的内存要有吧(想想就知道函数内部要根据内存块的大小交换数据实现排序),最后一个规则总要有吧,qsort的灵活性在于规则是活的不是死的,其实大多数语言的排序都是类似的机制啦。。。看下qsort的原型
void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
base就是所谓的首地址,nelem就是元素个数,width,就是每个元素的大小,fcmp是一个函数指针,这里函数的定义要类似于int cmp(const void*a,const void*b),其实很多人不知道怎么使用qsort主要是在于对这个函数不懂得如何写,其实想想就知道函数把每个元素的地址扔给比较函数,根据比较函数的返回值来决定到底是a在前面还是b在前面,所以在函数里面要先取出值,所以一般的写法就是
int cmp(const void*a,const void*b)
{
return *(T*)a-*(T*)b;
}
先强制转换成T类型再用取值符号*取出指,函数之所以用空指针是因为空指针可以指向任何类型,对于基本类型,只要将T修改为基本类型就行了,对于结构体之类的的指针,则return ((T*)a)-》x-((T*)b)-》x;其中T就是结构体的名称,x就是你要比较的字段,当然如果你要降序的话就将ab颠倒就行了,说了这么多,写一个例子,比如要对下面的数组排序
int a={2,10,5,4,0};
qsort(a,5,sizeof(int),cmp);
比较函数
int cmp(const void*a,const void*b)
{
return *(int*)a-*(int*)b;
}
。。呵呵,啰嗦了点。希望对你有帮助
21 1
查看全部3个回答
周围人还关注
超越轻卡
海外手游充值
c语言入门知识
c语言入门
变频直驱
六间房热舞
六间房直播间
如何学习
c++中的标准库函数qsort怎么用有什么作用
功 能: 使用快速排序例程进行排序
用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
参数:1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针,用于确定排序的顺序
亲 ,学会自己百度吧,不能太懒
C++中qsort怎么用
C++的qsort其实是一个回调函数,最重要的就是最后一个参数,它使用的是函数指针,使用的时候把某个函数名赋给这个函数指针就可以用了。所以关键的地方就是你如何定义这个compare函数了!楼上的同学例子给的很好,当然你还可以使用其他数据类型如float,double,char等等。 其实这个函数目的就是为了实现重载,因为它是用c语言写的,所以得用回调函数来实现重载。
谁能全面讲解下qsort函数,参数,使用方法,具体作用等等
六类qsort排序方法 前一段时间做题觉得qsort函数很好用, 但有时不太会用比如按结构体一级排序、二级排序、字符串排序等, 故通过查资料将其整理一番。 以下是其具体分类及用法(若无具体说明是以降序排列): 1、对一维数组排序: (Element_type是一位数组中存放的数据类型, 可以是char, int, float, double, etc ) 使用qsort之前,必须自己定义一个比较函数。 这个比较函数用于比较两个元素的大小。 由于qsort可以排序任意数据类型,包括自定义的结构类型, 因此,做一个自定义的比较函数是必要的。 int Comp(const void *p1,const void *p2 ) { return *((Element_type *)p2) 》 *((Element_type *)p1) ? 1 : -1; } int main() { Element_type list[MAX]; initial(list); qsort(list, sizeof(list),sizeof(Element_ type),Comp); // qsort的4个参数:数组的首地址、数组的实际大小, 元素的实际大小,比较函数 return 0; } 2、对字符串排序: int Comp(const void *p1,const void *p2) { return strcmp((char *)p2,(char *)p1); } int main() { char a[MAX1][MAX2]; initial(a); qsort(a,lenth,sizeof(a), Comp); //lenth 为数组a的长度 3、按结构体中某个关键字排序(对结构体一级排序): struct Node { double data; int other; }s; int Comp(const void *p1,const void *p2) { return (*(Node *)p2)-》data 》 (*(Node *)p1)-》data ? 1 : -1; } qsort(s,100,sizeof(s),Comp) ; 4、按结构体中多个关键字排序(对结构体多级排序)[ 以二级为例]: struct Node { int x; int y; }s; //按照x从小到大排序,当x相等时按y从大到小排序 int Comp(const void *p1,const void *p2) { struct Node *c = (Node *)p1; struct Node *d = (Node *)p2; if(c-》x != d-》x) return c-》x-d-》x; else return d-》y - c-》y; } 5、对结构体中字符串进行排序: struct Node { int data; char str; }s; //按照结构体中字符串 str 的字典序排序 int Comp(const void *p1,const void *p2) { return strcmp((*(Node *)p1).str,(*(Node *)p2).str); } qsort(s,100,sizeof(s,Comp); 6、计算几何中求凸包的Comp //以下是俺从别人那儿抄来的,暂时还没用过 int Comp(const void *p1,const void *p2) //重点Comp函数,把除了1点外的所有的点旋转角度排序 { struct point *c=(point *)p1; struct point *d=(point *)p2; if( cacl(*c, *d,p) 《 0) return 1; else if(!cacl(*c, *d, p) && dis(c-》x,c-》y,p.x,p.y) 《 dis(d-》x,d-》y,p.x,p.y ) ) //如果在一条直线上,则把远的放在前面 return 1; else return -1; } P.S.:qsort函数是ANSI C标准中提供的,其声明在stdlib.h文件中, 是根据二分发写的,其时间复杂度为n*log(n),其结构为: void qsort(void *base,size_t nelem,size_t width,int (*Comp)(const void *,const void *)); 其中: *base 为要排序的数组 nelem 为要排序的数组的长度 width 为数组元素的大小(一字节为单位) (* Comp)(const void *p1,const void *p2) 为判断大小函数的指针,这个函数需要自己定义,如果p1》p2, 函数返回-1;a《b,函数返回1;a==b函数返回0。
希望采纳

更多文章:
dropdownlist 绑定(DropDownList 绑定所有项 并 显示指定项)
2026年10月11日 08:50
易语言网页api接口怎么调用(易语言,怎么读取网页json的api)
2026年10月11日 08:00
majority of(the majority of 和 a majority of的区别以及用法例句)
2026年10月11日 07:40
another time(another time和other time的区别)
2026年10月11日 05:00






