目录
1.C:qsort
函数介绍
qsort函数是C语言提供的库函数,可以将任何无序数据排列成有序数据,本质上是通过指针移动和快速排序完成对数组内部数据的排序,并放回原数组中
#include <stdlib.h> //包含qsort函数的头文件
//参数
int qsort(void* base,size_t num,size_t width,int(*compare)(const void* p1,const void* p2))
参数1:void* base指向未知类型的待排序数组
参数2:size_t num,其中size_t是以字节为单位的数据类型,这个参数要传入数组中的元素个数
参数3:size_t width,是数组类型的大小(sizeof(int))
参数4:int(*compare)(const void* p1,const void* p2)
这是一个返回值为int类型,参数为const void* p1,const void* p2的函数指针,这个参数要传入的是编程人员已经写好的自定义函数,也就是说这个函数是我们自己实现的
在使用qsort函数时编译器无法提前预知待排序数组的类型是什么,所以函数指针compare指向的应该是一个能够返回两个元素比较结果的函数
C++规定compare函数的返回值是<0,=0,>0三种情况
如果p1>p2,返回值大于0
如果p1=p2,返回值等于0
如果p1<p2,返回值小于0
MyType可以是任何类型,不管是对char还是int型数组排序,只需将MyType替换为对应的数据类型即可
int compareMyType (const void * a, const void * b)
{
if ( *(MyType*)a < *(MyType*)b ) return -1;
if ( *(MyType*)a == *(MyType*)b ) return 0;
if ( *(MyType*)a > *(MyType*)b ) return 1;
}
//更加简洁的写法
int compareMyType (const void * a, const void * b)
{
return *(MyType*)a - *(MyType*)b;//默认正序
//return *(MyType*)b - *(MyType*)a;//倒序
}
整型排序
int cmp_int(const void* p1, const void* p2)
{
//将void*转换为int*后再返回比较结果
return *(int*)p1 - *(int*)p2;
}
int main()
{
int arr[10] = { 3,9,4,1,7,3,2,6,79,65 };
int sz = sizeof(arr) / sizeof(arr[0]);//数组元素个数
qsort(arr, sz, sizeof(int), cmp_int);//调用qsort
for (int i = 0; i < 10; i++)
printf("%d ", arr[i]);
}
字符型排序
排序字符时是按照ASCII码表的顺序进行排序
int cmp_char(const void* p1, const void* p2)
{
//将void*转换为char*后再返回比较结果
return *(char*)p1 - *(char*)p2;
}
int main()
{
char arr[6] = { 'c','b','g','a','s','\0' };
int sz = sizeof(arr) / sizeof(arr[0]);//数组元素个数
qsort(arr, sz, sizeof(char), cmp_char);//调用qsort
for (int i = 0; i < 6; i++)
printf("%c ", arr[i]);
}
结构体类型排序
考虑到结构体内部的不同成员,在排序结构体时要对每一个排序的结构体成员单独设计函数。
struct Stu
{
char name[20];
int age;
};//定义结构体
int cmp_stu_name(const void* p1, const void* p2)
{
//p1和p2都指向结构体数组内的元素,所以在返回时应强制转换为结构体指针->struct Stu*
return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
int main()
{
struct Stu arr[3] = { {"zhangsan",35},
{"lisi",29},
{"wangwu",18} };//定义结构体数组并初始化
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(struct Stu), cmp_stu_name);//比较姓名
for (int i = 0; i < 3; i++)
printf("%s\n", arr[i].name);
return 0;
}
如果排序年龄再设计函数cmp_int专门比较年龄,方法同上文整型排序,不在过多赘述。
这里说一下字符串比较函数strcmp,头文件 #include<string.h>
strcmp是专门用于字符串比较的函数,它是按照字符串中字符的ASCII码值的大小来排序,用在这里可以通俗的认为按照姓名首字母先后来排序。
他的参数
int strcmp ( const char * str1, const char * str2 ); //str1和str2是被比较的两个字符串指针
他的返回值:
str1>str2 返回值 >0
str1=str2 返回值 =0
str1<str2 返回值 <0
巧妙的是strcmp的返回值刚好和我们设计的比较函数的返回值重合,那么strcmp的返回值也可以当作函数的返回值。
2.C++:sort
函数介绍
在C++中,sort函数是比qsort函数更加高级的函数,包含库
#include <algorithm>
sort()并非只是普通的快速排序,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。根据不同的数量级别以及不同情况,能自动选用合适的排序方法。当数据量较大时采用快速排序,分段递归。一旦分段后的数据量小于某个阀值,为避免递归调用带来过大的额外负荷,便会改用插入排序。而如果递归层次过深,有出现最坏情况的倾向,还会改用堆排序。可以直接使用sort()来对数据进行排序,而不需手动编写排序函数。
他的参数
void sort (RandomAccessIterator first, RandomAccessIterator last);
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
第一个参数:first排序开始的位置
第二个参数:last排序结束的位置
第三个参数:可写可不写,不写默认升序排列,如果需要降序则额外传入函数
函数自定义类型为bool
- 如果返回值为true,表示num1和num2顺序需要交换,例如num1>num2是true,说明num1和num2的顺序交换,即倒序
- 如果返回值为false,表示num1和num2顺序不需要交换,例如num1>num2是false(num1<num2),说明num1和num2的顺序不交换,即顺序
bool cmp(int num1, int num2) { return num1 > num2; // 可以简单理解为 > 降序排列; < 升序排列 }
升序
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr[10] = { 12,43,2,57,29,99,56,4,6,200 };
sort(arr, arr + 10);//默认升序
for (int i = 0; i < 10; i++)
cout << arr[i] << ' ';
}
//arr指针指向数组首地址,arr+10跳过10个整型元素指向数组中最后一个元素
降序
#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int num1, int num2)
{
return num1 > num2;
}
int main()
{
int arr[10] = { 12,43,2,57,29,99,56,4,6,200 };
sort(arr, arr + 10, cmp);//传参cmp后降序
for (int i = 0; i < 10; i++)
cout << arr[i] << ' ';
}