qsort函数、sort函数 (精心整理篇)

本文详细介绍了C语言中的qsort和sort函数的使用方法及特性,包括它们对连续内存数据的排序过程、参数意义、compare函数的实现方式以及在不同数据类型(如int、char、double、结构体等)和复杂排序场景下的应用。同时,对比了qsort和sort函数之间的区别,强调了sort作为qsort的升级版在某些场景下的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

qsort函数、sort函数 (精心整理篇)

转载:http://www.cnblogs.com/ForeverJoker/archive/2013/05/25/qsort-sort.html

先说明一下qsort和sort,只能对连续内存的数据进行排序,像链表这样的结构是无法排序的。

首先说一下, qsort

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

具体介绍:-^^

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

int compare (const void *elem1, const void *elem2 ) );

qsort(即,quicksort)主要根据你给的比较条件给一个快速排序,主要是通过指针移动实现排序功能。排序之后的结果仍然放在原来数组中。

参数意义如下:

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

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

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

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

我们来简单讨论compare这个比较函数(写成compare是我的个人喜好,你可以随便写成什么,比如 cmp 什么的,在后面我会一直用cmp做解释)。
典型的compare的定义是int compare(const void *a,const void *b);

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

qsort 的使用方法:

一、对int类型数组排序

int num[100];

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

{

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

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

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

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

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

*/

}

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

示例完整函数(已在 VC6.0上运行通过):

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

二、对char类型数组排序(同int类型)

char word[100];

int cmp( const void *a , const void *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];

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

{

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

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

}

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

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

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

四、对结构体一级排序

struct In

{

double data;

int other;

}s[100]

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

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

{

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

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

//或者你可以将这上面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

{

int x; //你可以比喻成:失败次数

int y; //你可以比喻成:成功次数

}s[100];

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

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

{

struct In *c = (In *)a;

struct In *d = (In *)b;

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

else return d->y - c->y;

}

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

六、对字符串进行排序

struct In

{

int data;

char str[100];

}s[100];

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

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

{

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

}

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

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

再说说 sort (常用于 C++ )

sort 使用时得注明:using namespace std; 或直接打 std::sort() 还得加上 #include <algorithm> 头文件

例:

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

int a[20];

   for(int i=0;i<20;++i)

cin>>a[i];

  sort(a,a+20); //范围,很明显这里是a+20 注意,这是必要的,如果是a+19

for(i=0;i<20;i++) //最后一个值a[19]就不会参与排序。

cout<<a[i]<<endl;

return 0;

}

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

最后,我们来说说sort、qsort的区别:

sort是qsort的升级版,如果能用sort尽量用sort,使用也比较简单,不像qsort还得自己去写 cmp 函数,只要注明 使用的库函数就可以使用,参数只有两个(如果是普通用法)头指针和尾指针;

默认sort排序后是升序,如果想让他降序排列,可以使用自己编的cmp函数

#include<iostream>
#include<algorithm>
using namespace std;
int cmp(int a,int b)
{
if(a<b)
return 1; //升序排列,如果改为 a >b,则为降序,要注意sort()中cmp()的返值只有1和0,不像qsort中存在-1!!!!
else
return 0;
}


int main(){
int i;
int a[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<<a[i]<<endl;
system("pause");
return 0;
}

对二维数组的排序:
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;

bool cmp(int *p,int *q)
{
if(p[0]==q[0])
{
if(p[1]==q[1])
{
return p[2]<q[2];
}
else return p[1]<q[1];
}
else return p[0]<q[0];
}
int main()
{
srand(time(0));
int i;
int **a=new int*[1000];
for(i=0;i<1000;++i)
{
a[i]=new int[3];
a[i][0]=rand()%1000;
a[i][1]=rand()%1000;
a[i][2]=rand()%1000;
//printf("%d\t%d\t%d\n",a[i][0],a[i][1],a[i][2]);
}
sort(a,a+1000,cmp);
/*cout<<"After sort"<<endl;
for(i=0;i<1000;++i)
{
printf("%d\t%d\t%d\n",a[i][0],a[i][1],a[i][2]);
}*/
return 0;
}

转载: http://www.cnblogs.com/ForeverJoker/archive/2013/05/25/qsort-sort.html
 
<think>好的,我现在需要回答用户关于C语言中sort函数qsort函数区别的问题。首先,我要确认用户的问题点在哪里。用户可能已经知道这两个函数都是用于排序的,但想了解它们的具体区别,比如用法、性能、适用场景等。 首先,我需要回忆这两个函数的基本信息。根据提供的引用,qsort是C标准库中的函数,而sort在C语言中可能是指用户自己实现的,或者是C++中的std::sort?不过根据引用[1]和[2],似乎用户可能混淆了C和C++中的函数。比如,C语言本身没有sort函数,而C++的STL中有std::sort。这可能是一个关键点。因此,用户的问题可能需要先澄清,C语言中的sort函数是否存在,或者是否指的是某些特定实现的函数。 根据提供的引用内容,引用[1]提到C语言中的qsort和C++中的sort函数。因此,可能用户的问题中的“sort函数”指的是C++中的std::sort,而qsort是C语言的标准库函数。因此,区别主要在于C和C++的不同实现。这可能是一个重要的区别点,需要明确告诉用户。 接下来,我需要整理两者的区别。根据引用[1],qsort的比较函数使用函数指针,而sort使用模板或函数对象,提供更灵活的比较规则。引用[2]提到std::sort是改进版的qsort,采用更高效的算法,比如三路划分,对不同大小的数组采用不同方法,性能更好。 另外,类型安全方面,qsort使用void指针,需要用户进行类型转换,容易出错;而C++的sort是类型安全的,因为模板会自动推断类型。这也是一个关键区别。 然后,关于性能,qsort因为是通用实现,可能有更多的开销,而sort针对不同数据类型优化,效率更高。引用[2]指出std::sort对大数组使用9项取样,更细致的排序策略,所以更快。 还有,使用方式上,qsort需要显式传递比较函数,参数包括元素大小和数量;而sort的参数更简洁,直接传迭代器和比较函数(可选)。 需要注意的是,C语言本身没有内置的sort函数,用户可能提到的sort可能是某个库或自己实现的函数,但标准库中只有qsort。而C++中的std::sort属于STL的一部分,所以用户可能在比较C的qsort和C++的sort。因此,在回答时需要明确这一点,避免混淆。 现在,我需要将这些点组织成一个结构清晰的回答,分点列出区别,并引用提供的资料来支持。同时,用户可能需要示例代码来理解两者的用法差异,比如qsort需要自己写比较函数,而sort可能更简洁。 另外,用户的问题中提到的是C语言中的sortqsort,但根据引用,可能用户将C++的sort与C的qsort对比了。因此,在回答时需要指出这一点,避免误解。比如,说明在C语言中标准库只有qsort,而sort属于C++的STL。 最后,生成相关问题,帮助用户进一步学习,比如关于qsort的比较函数实现,或者性能优化的方法等。 总结回答的结构: 1. 明确两个函数所属的语言标准:qsort属于C标准库,sort属于C++ STL。 2. 比较函数的实现方式:函数指针 vs 模板/函数对象。 3. 类型安全性:void指针需要手动转换 vs 自动类型推断。 4. 性能差异:算法优化,如三路划分。 5. 使用示例,代码对比。 6. 应用场景:C项目 vs C++项目。 7. 引用相关文献支持各点。 在回答中,需要确保术语准确,比如qsort的参数(base, num, size, compar),而sort的参数(迭代器,比较函数)。同时,注意用户可能混淆C和C++的情况,需明确指出。 现在,我需要检查是否有遗漏的点,比如内存操作、错误处理等方面是否有差异。根据引用[4],qsort的比较函数需要注意解引用和类型转换,而sort则不需要,这也是类型安全的一部分。 最后,确保回答符合用户要求的结构:分点清晰,使用中文,正确引用,并生成相关问题。</think>### C语言中sort函数qsort函数的区别 在C语言中,标准库仅提供`qsort`函数,而`sort`函数实际上是C++标准模板库(STL)中的一部分。因此,两者的主要区别源于C与C++语言特性及实现方式的不同。以下是具体对比: --- #### 1. **语言标准与归属** - **qsort**:C语言标准库函数,定义在`<stdlib.h>`中[^1][^3]。 - **sort**:C++ STL中的函数,定义在`<algorithm>`中[^1][^2]。 --- #### 2. **比较函数的实现方式** - **qsort**: 需通过**函数指针**传递比较函数函数原型为: ```c int compare(const void* a, const void* b); ``` 用户需自行处理`void*`类型转换,例如: ```c int cmp_int(const void* a, const void* b) { return *(int*)a - *(int*)b; } ``` 使用示例: ```c qsort(arr, n, sizeof(int), cmp_int); ``` [^4] - **sort**: C++中使用**模板**和**函数对象**(如Lambda表达式)定义比较规则,支持更灵活的语法: ```cpp std::sort(arr.begin(), arr.end(), [](int a, int b) { return a < b; }); ``` 类型自动推断,无需手动转换[^2]。 --- #### 3. **类型安全性** - **qsort**: 基于`void*`指针操作元素,需用户强制类型转换,容易引发错误(如指针解引用错误)[^4]。 - **sort**: 模板机制确保类型安全,编译器自动检查类型匹配,减少运行时错误。 --- #### 4. **性能优化** - **qsort**: 通用排序实现,对任何数据类型采用相同的算法(通常为快速排序),未针对特定数据优化。 - **sort**: 采用混合排序策略(如快速排序+插入排序),对大数组使用**三路划分**和**9项取样**优化,避免最坏时间复杂度;对小数组直接插入排序。整体效率更高。 --- #### 5. **使用复杂度** - **qsort**: 需手动指定元素数量、元素大小,代码较繁琐: ```c qsort(arr, n, sizeof(element), compare); ``` - **sort**: 通过迭代器操作,参数简洁: ```cpp std::sort(arr.begin(), arr.end()); ``` --- #### 6. **应用场景** - **qsort**: 适用于纯C项目或需兼容C的代码,但对自定义数据类型排序时代码较复杂。 - **sort**: 适用于C++项目,支持泛型编程,尤其适合容器(如`vector`、`array`)和复杂对象排序[^2]。 --- ### 总结对比表 | 特性 | qsort (C) | sort (C++) | |--------------|------------------------------------|-------------------------------------| | **类型安全** | 低(需手动类型转换) | 高(自动类型推断) | | **性能** | 一般 | 更优(混合算法优化) | | **语法简洁性** | 复杂(需传递元素大小、数量) | 简单(迭代器直接操作) | | **扩展性** | 依赖函数指针 | 支持Lambda、函数对象 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值