C++:qsort和sort函数详解

目录

 1.C:qsort

函数介绍

整型排序

字符型排序

​编辑

结构体类型排序

2.C++:sort

函数介绍

 升序

 降序


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] << ' ';
}

  • 89
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 27
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深情秋刀鱼@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值