关于排序问题,平时我们在工作中会经常遇到,刚好最近看了几个关于库函数排序的博客,觉得写得都不错,为了方便今后能够方便使用,今天就花点时间总结一下(其实前段时间对于sort的用法也写过两个博客),sort()与qsort()的时间复杂度都为O(nlogn),都算是比较好的排序方法
关于sort使用方法的讨论(把数组排成最小的数)
华为OJ-奥运会排行榜C++
排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等。 看名字都知道快速排序是目前公认的一种比较好的排序算法。因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用。 这就是qsort函数(全称quicksort)。它是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,其时间复杂度为n*log(n)
原型:
_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*));
参数: 1 待排序数组,排序之后的结果仍放在这个数组中
2 数组中待排序元素数量
3 各元素的占用空间大小(单位为字节)
4 指向函数的指针,用于确定排序的顺序(需要用户自定义一个比较函数)
解释: qsort ( 数组名 ,元素个数,元素占用的空间(sizeof),比较函数)
比较函数是一个自己写的函数 遵循 int com(const void *a,const void *b) 的格式。
当a b关系为 > < = 时,分别返回正值 负值 零 (或者相反)。
使用a b 时要强制转换类型,从void * 转换回应有的类型后,进行操作。
数组下标从零开始,个数为N, 下标0-(n-1)。
//对int型数组排序
#include
#include
using namespace std;
int compare(const void *a,const void *b)
{
return *(int*)b-*(int*)a;//降序
}
int main()
{
int a[]={2,4,1,23,5,76,0,43,24,65};
int i, len = sizeof(a) / sizeof(int);
for(i=0;i<len;i++)
cout<<a[i]<< ' ';
cout << endl;
qsort(a,len,sizeof(int),compare);
for(i=0;i<len;i++)
cout<<a[i]<< ' ';
return 0;
}
qsort要求提供一个自己定义的比较函数。比较函数使得qsort通用性更好,有了比较函数qsort可以实现对数组、字符串、结构体等结构进行升序或降序排序。
//对char型数组排序
#include
#include
#include
using namespace std;
int compare(const void *a, const void *b)
{
return *(char*)a - *(char*)b; //升序
}
int main()
{
char a[]= "hello";
int i, len = strlen(a);
for(i=0;i<len;i++)
cout<<a[i]<< ' ';
cout << endl;
qsort(a,len,sizeof(char),compare);
for(i=0;i<len;i++)
cout<<a[i]<< ' ';
return 0;
}
//对double型数组排序
#include
#include
using namespace std;
int compare(const void *a,const void *b)
{
return *(double*)a > *(double*)b ? 1 : -1;//升序
}
int main()
{
double a[]={2,4,1,23,5,76,0,43,24,65};;
int i, len = sizeof(a) / sizeof(double);
for(i=0;i<len;i++)
cout<<a[i]<< ' ';
cout << endl;
qsort(a,len,sizeof(double),compare);
for(i=0;i<len;i++)
cout<<a[i]<< ' ';
return 0;
}
/*在对浮点或者double型的一定要用三目运算符,因为要是使用像整型那样相减的话,如果是两个很接近的数则可能返回一个很小的小数(大于-1,小于1),而cmp的返回值是int型,因此会将这个小数返回0,系统认为是相等,失去了本来存在的大小关系*/
Sort()函数是c++一种排序方法之一,学会了这种方法也打消我学习c++以来使用的冒泡排序和选择排序所带来的执行效率不高的问题!因为它使用的排序方法是类似于快排的方法,时间复杂度为n*log(n),执行效率较高!
要使用此函数只需用#include
sort(begin,end)对于只有两个参数的sort,默认是升序排列,如果对于复杂的数据类型排序,需要重载operator<运算符
调用三个参数的sort:sort(begin,end,compare)就成了。对于list容器,这个方法也适用,把compare作为sort的参数就可以了,即:sort(compare).
自己编写compare函数:
bool compare(int a,int b)
{
return ab,则为降序
}
下面这个是3个参数的一个典型问题
关于sort使用方法的讨论(把数组排成最小的数)
其实对于这么简单的任务(类型支持“<”、“>”等比较运算符),完全没必要自己写一个类出来。标准库里已经有现成的了,就在functional里,include进来就行了。functional提供了一堆基于模板的比较函数对象。它们是(看名字就知道意思了):equal_to、not_equal_to、greater、greater_equal、less、less_equal。对于这个问题来说,greater和less就足够了,直接拿过来用:
升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()).
更进一步,让这种操作更加能适应变化。也就是说,能给比较函数一个参数,用来指示是按升序还是按降序排,这回轮到函数对象出场了。
为了描述方便,我先定义一个枚举类型EnumComp用来表示升序和降序。很简单:
enum Enumcomp{ASC,DESC};
然后开始用一个类来描述这个函数对象。它会根据它的参数来决定是采用“<”还是“>”。数组也可以使用sort函数排序
#include
#include
enum Enumcomp{ASC,DESC};
class compare
{
private:
Enumcomp comp;
public:
compare(Enumcomp c):comp(c) {};
bool operator () (int num1,int num2)
{
switch(comp)
{
case ASC:
return num1 < num2;
case DESC:
return num1 > num2;
}
return true;//为了防止告警,其实没有实际用途
}
};
int main()
{
int myints[] = {32, 14, 25, 47, 29, 11, 98, 56};
std::sort(myints, myints + sizeof(myints) / sizeof(int), compare(DESC));
for (int x : myints)
std::cout << x << " ";
return 0;
}
//接下来使用 sort(begin,end,compare(ASC)实现升序,
//sort(begin,end,compare(DESC)实现降序。
//不用switch
#include
#include
struct myclass
{
bool operator()(int i, int j){return i > j;}
} myobject;
int main()
{
int myints[] = {32, 14, 25, 47, 29, 11, 98, 56};
std::sort(myints, myints + sizeof(myints) / sizeof(int), myobject);
for (int x : myints)
std::cout << x << " ";
return 0;
}
参考博文:
https://blog.csdn.net/zzzmmmkkk/article/details/4266888/
https://blog.csdn.net/zhao888789/article/details/79186619