目录
前言
以下我们来学习c语言的 qsort() 排序 和C++的 sort() 排序。
一、qsort()是什么?
qsort() 是 C 标准库中的一个函数,用于对数组进行快速排序。它的全称是 “quick sort”,因为它实现了一种高效的排序算法。qsort() 可以对任何类型的数据进行排序,只要你提供一个合适的比较函数。头文件 #include <stdlib.h>。
1.核心代码:
函数的原型
void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
参数含义:
① void * base:待排序数组的首地址。
② size_t num:数组元素的个数。
③ size_t size:一个数组元素的大小(所占字节数)。
④ int ( * comparator ) ( const void , const void * ):首先它是一个函数指针,指向的函数是排序函数;其此所包含的两个参数为所比较元素的地址;最后是参数类型为void的原因是它的独特之处,可以接收任意类型的参数。
实际使用(一般只对qsor()函数进行微调)
qsort ( arr,sizeof(arr)/sizeof(arr[0]),sizeof(arr[0),cmp );
int cmp( const void * elem1, const void * elem2 )//整形为例
{
return *(int*)elem1-*(int*)elem2;
}
以整形数组进行演示
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* elem1, const void* elem2)
{
return *(int*)elem1 - *(int*)elem2;//elem1-elem2为从小到大排序,elem2-elem1为从大到小排序
}
int main()
{
int arr[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
输出:
2.其他类型比较
一级排序
1.字符数组:
int cmp_char(const void* elem1, const void* elem2)
{
return *(char*)elem1 - *(char*)elem2;//elem1-elem2为从小到大排序,elem2-elem1为从大到小排序
}
2.浮点数组:
int cmp_double(const void* elem1, const void* elem2)
{
return *(double*)elem1 > *(double*)elem2 ? 1 : -1;//从小到大,如果想从大到小(1和-1交换位置)
//返回值的问题,显然cmp返回的是一个整型,所以避免double返回小数而被丢失,用一个判断返回值。
//不可以用减号连接
}
int cmp_float(const void* p1, const void* p2)
{
return *((float*)p1) - *((float*)p2);//elem1-elem2为从小到大排序,elem2-elem1为从大到小排序
}
3.字符串长度进行排序:
int cmp_string(const void* elem1, const void* elem2)
{
return strlen((char * )elem1) > strlen((char * )elem2) ? 1 : -1; //从小到大,如果想从大到小(1和-1交换位置)
//不可以用减号连接
}
4.字符串首字母:
int cmp_string(const void* elem1, const void* elem2)
{
//char arr[6][10] = { "grape", "face", "dog", "cat", "black", "apple" };
return *(char*)elem1 - *(char*)elem2; //elem1-elem2为从小到大排序,elem2-elem1为从大到小排序
}
5.字符串str的字典顺序排序:
struct Zfc//结构体类型
{
int data;
char str[100];
}s[100];
int cmp ( const void *elem1 , const void *elem2)
{
return strcmp( (*(Zfc *)elem1).str , (*(Zfc*)elem2).str);//elem1-elem2为从小到大排序,elem2-elem1为从大到小排序
}
int cmp_string(const void* elem1, const void* elem2)//二维数组类型
{
//char arr[6][10] = { "grape", "face", "dog", "cat", "black", "apple" };
return strcmp((char*)elem1,(char*)elem2);//elem1-elem2为从小到大排序,elem2-elem1为从大到小排序
}
二级排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student
{
char name[20];
int grade;
}Student;
int cmp_s(const void* elem1, const void* elem2)//先对学生名字进行排序,再对成绩进行排序
{
if ((strcmp(((Student*)elem1)->name, ((Student*)elem2)->name))!=0)
return strcmp(((Student*)elem1)->name, ((Student*)elem2)->name);//转换类型,先对学生名字进行字典排序
else
return ((Student*)elem1)->grade - ((Student*)elem2)->grade;//转换类型,如果名字相同则对成绩进行排序
//成绩如果是浮点型则参考上面浮点数组
}
int main()
{
Student s[] = { { "yi", 89 }, { "er", 100 }, { "san", 101 }, { "si", 121 }, { "wu", 95 }, {"liu",78} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_s);
for (int i = 0; i < sz; i++)
{
printf("%s %d\n", s[i].name,s[i].grade);
}
return 0;
}
输出:
多级排序
参考二级排序。在原来的基础上对结构体进行添加元素,通过if…else if 进行连接,排序的优先级从上到下,每一层排序规则参考一级排序。
二、sort()是什么?
在 C++ 中,sort() 是一个用于对容器中的元素进行排序的函数,sort() 函数可以对任意随机访问迭代器支持的容器(如数组、std::vector、std::deque 等)进行排序。其来自 C++ 标准库中的 #include <?> (?=algorithm,打上去显示不出来,凑合看) ,建议用万能头文件 #include<bits/stdc++.h> 。
1.自动调用(从小到大)
void sort (*begin,*end);/对[*begin,*end)内的数据进行排序,左闭右开
代码举例:
#include<bits/stdc++.h>
using namespace std;
// #include<algorithm>
int a[20]={1,3,6,5,4,9,8,2,7,4};
int main(){
sort(a+3,a+9);//左闭右开,默认从小到大,从下标3到第8个进行排列
for(int i:a)
cout << i <<" ";
return 0;
}
输出:—
2.自定义调用
一级排序
bool cmp(int a,int b){
if(a<b) return 1;
return 0;
//return a>b;
}
sort(a,a+10,cmp);//左闭右开,默认从小到大
以整形数组进行举例:
#include<bits/stdc++.h>
using namespace std;
int a[10]={1,3,6,5,4,9,8,2,7,6};
bool cmp(int a,int b){
if(a<b) return 1;//只能>或者<不能是>=或者<=!!!!!!
return 0;
//return a>b;
}
int main(){
sort(a,a+9,cmp);//左闭右开,默认从小到大,从下标0到第8个进行排列
for(int i:a)
cout << i <<" ";
return 0;
}
输出:
多级排序
优先级参考C语言的qsort()函数,自上到下,通过if…else if…进行连接(区别在于比较的符号由"-“改为”>“或”<")
以结构体进行举例:
#include<bits/stdc++.h>
using namespace std;
struct score
{
string Name="a";
int Chinese;
int Math;
int sum;
};
bool cmp(score a,score b){//可通过改变">"或"<"从而改变排序规则,只能>或者<不能是>=或者<=!!!!!!
if(a.sum!=b.sum) return a.sum>b.sum;//优先比较总分,升序
if(a.Chinese!=b.Chinese) return a.Chinese>b.Chinese;//其次比较语文成绩,降序
else return a.Math>b.Math;//最后比较数学成绩,升序
}
int main(){
score a[10];
srand((unsigned) time(NULL));//随机生成成绩
for(int i=0;i<10;i++){
a[i].Name+=to_string(i+1);//自动生成学生名字
a[i].Chinese=rand()%101;
a[i].Math=rand()%101;
a[i].sum=a[i].Chinese+a[i].Math;
}
sort(a,a+10,cmp);//排序!!!!!!!!!!!!!!!!!
cout << "名字" << "\t" << "总分" << "\t"<< "语文" << "\t"<< "数学" << endl;//打表
for(int i=0;i<10;i++){
cout << a[i].Name << "\t";
cout << a[i].sum << "\t";
cout << a[i].Chinese << "\t";
cout << a[i].Math << "\t";
cout << endl;
}
return 0;
}
输出:
三.sort() 排序和qsort() 排序的区别及各自特点
以上就是今天要讲的内容,本文介绍了sort() 排序和qsort() 排序的使用,
sort() 和 qsort() 在排序功能上有相似之处,但它们的实现方式、使用场景和接口存在显著区别。下面我们将详细对比这两个函数的区别及各自的优缺点。
- 基本区别
qsort()
语言 :C 语言标准库函数
函数签名:void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *))
函数签名: 通过用户提供的比较函数支持任意数据类型
排序方式: 非稳定排序
数据类型: 处理任何类型数据,需进行类型转换
sort()
语言 :主要在高级语言(如 Python、Java、C++ STL)
函数签名:依赖于具体语言,通常为方法或全局函数
函数签名:依赖于具体语言,通常为方法或全局函数
排序方式:语言层面多为稳定排序,与实现有关
数据类型:根据语言支持数据类型,通常是具体类型
- 优缺点
qsort()
优点:
通用性:qsort() 可以对任何类型的数据进行排序,只需提供相应的比较函数,非常灵活。
高效性:在许多情况下,qsort() 的实现非常高效,尤其是在处理原始数据类型数组时。
标准化:作为 C 语言标准库的一部分,qsort() 是广泛认可的标准排序函数,适用于许多系统层面的开发。
缺点:
复杂性:由于需要提供函数指针作为参数,使用 qsort() 的代码往往比使用 sort() 更复杂,不够直观。
非稳定性:qsort() 是非稳定排序,即相同元素的相对位置在排序后可能会发生变化。
类型处理:使用 qsort() 前,需要显式处理数据类型,必须将基本类型转换为 void * 类型,这增加了出错的可能性。
sort()
优点:
易用性:sort() 通常提供简单明了的接口,易于理解和使用。开发者可以轻松调用方法或函数进行排序。
稳定性:在一些语言实现中,sort() 是稳定排序,意味着相等元素的相对顺序保持不变。这在某些应用场景(如多重排序)中是非常有用的。
语言特性:许多现代语言的 sort() 方法支持对对象和复杂数据结构的直接排序,支持 Lambda 表达式、编程态等现代编程特性,使用灵活。
缺点:
性能差异:在某些特定场景下,sort() 的底层实现可能不如 qsort() 高效,尽管这种情况不常见。
实现依赖:具体的实现可能依赖于语言的版本和库,因此可能存在不一致性。