首页 > 其他分享 >sort() 排序和qsort() 排序(超详细)

sort() 排序和qsort() 排序(超详细)

时间:2024-10-31 21:47:22浏览次数:3  
标签:sort const int elem2 void qsort elem1 排序

目录


前言

以下我们来学习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() 在排序功能上有相似之处,但它们的实现方式、使用场景和接口存在显著区别。下面我们将详细对比这两个函数的区别及各自的优缺点。

  1. 基本区别
    qsort()
    语言 :C 语言标准库函数
    函数签名:void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *))
    函数签名: 通过用户提供的比较函数支持任意数据类型
    排序方式: 非稳定排序
    数据类型: 处理任何类型数据,需进行类型转换

    sort()
    语言 :主要在高级语言(如 Python、Java、C++ STL)
    函数签名:依赖于具体语言,通常为方法或全局函数
    函数签名:依赖于具体语言,通常为方法或全局函数
    排序方式:语言层面多为稳定排序,与实现有关
    数据类型:根据语言支持数据类型,通常是具体类型

  1. 优缺点
    qsort()
    优点:
    通用性:qsort() 可以对任何类型的数据进行排序,只需提供相应的比较函数,非常灵活。
    高效性:在许多情况下,qsort() 的实现非常高效,尤其是在处理原始数据类型数组时。
    标准化:作为 C 语言标准库的一部分,qsort() 是广泛认可的标准排序函数,适用于许多系统层面的开发。

    缺点:
    复杂性:由于需要提供函数指针作为参数,使用 qsort() 的代码往往比使用 sort() 更复杂,不够直观。
    非稳定性:qsort() 是非稳定排序,即相同元素的相对位置在排序后可能会发生变化。
    类型处理:使用 qsort() 前,需要显式处理数据类型,必须将基本类型转换为 void * 类型,这增加了出错的可能性。


    sort()
    优点:
    易用性:sort() 通常提供简单明了的接口,易于理解和使用。开发者可以轻松调用方法或函数进行排序。
    稳定性:在一些语言实现中,sort() 是稳定排序,意味着相等元素的相对顺序保持不变。这在某些应用场景(如多重排序)中是非常有用的。
    语言特性:许多现代语言的 sort() 方法支持对对象和复杂数据结构的直接排序,支持 Lambda 表达式、编程态等现代编程特性,使用灵活。

    缺点:
    性能差异:在某些特定场景下,sort() 的底层实现可能不如 qsort() 高效,尽管这种情况不常见。
    实现依赖:具体的实现可能依赖于语言的版本和库,因此可能存在不一致性。

标签:sort,const,int,elem2,void,qsort,elem1,排序
From: https://blog.csdn.net/2302_81416927/article/details/143414928

相关文章

  • 数组排序简介-计数排序(Counting Sort)
    基本思想        通过统计数组中每个元素在数组中出现的次数,根据这些统计信息将数组元素有序的放置到正确位置,从而达到排序的目的。算法步骤计算排序范围:遍历数组,找出待排序序列中最大值元素 nums_max和最小值元素 nums_min,计算出排序范围为 nums_max−nums_min......
  • 数组排序简介-快速排序(Quick Sort)
    基本思想        采用经典的分治策略,选择数组中某个元素作为基准数,通过一趟排序将数组分为独立的两个子数组,一个子数组中所有元素值都比基准数小,另一个子数组中所有元素值都比基准数大。然后再按照同样的方式递归的对两个子数组分别进行快速排序,以达到整个数组有序。......
  • order by 、sort by、distribute by、group by、cluster by的区别
    1.orderby:用途:主要用于对查询结果进行排序。返回的结果集是全局有序的。SELECT*FROMemployeesORDERBYsalaryDESC;2.SORTBY用途:主要用于对分布式查询结果进行排序。每个节点(分区)分别进行排序,但返回的结果集不一定全局有序。适用于Hive等大数据处理系统。SELEC......
  • 拓扑排序
    拓扑序1、在做DAGDP时,按拓扑序转移,状态可转移完全2、从拓扑序小的点连向拓扑序大的点,一定不会成环3、统计结点\(x\)可以到达的点数(待解决)DirectingEdges根据性质2,对有向边构成的图跑拓扑,拓扑序小的连向大的即可正确性由性质2易知,待证明P3953[NOIP2017提高组]逛公园本......
  • Day26--冒泡排序
    Day26--冒泡排序冒泡排序无疑是最为出名的排序算法之一:总共有八大排序!冒泡的代码还是相当简单的,两层循环:外层冒泡轮数,里层依次比较:江湖中人人尽皆知。我们看到嵌套循环:应该立马就可以得出这个算法的时间复杂度为O(n²)。思考:如何优化?1.冒泡排序的思路理解:一、冒泡排序的起......
  • qsort排序
    在体操比赛中,每位选手的得分是由多名裁判综合打分所得。现在已经汇总了N名选手的个人总得分(选手的编号依次为1,2,……N),请你设计程序找出第K名选手在所有选手中的排名。输入说明:第一行是N和K,N表示运动员的个数,K是选手序号;第二行依次是这N位运动员的个人总得分。输出说明:第K名(从1开......
  • xtu oj 逆序数(小数据) //冒泡排序
    题目描述给你一个序列x1,x2,…,xn,如果数对<xi,xj>,其中i<j,而xi>xj我们称之为逆序数对。一个序列的逆序数对的数目,称为这个序列的逆序数。比如说序列312,逆序数对为<3,1>和<3,2>,所以这个序列的逆序数为2。现在给你一个数字序列,请求其逆序数。输入每个样例为两行......
  • 项目进度计划中的任务如何优先排序
    项目进度计划中的任务优先排序取决于多个因素:任务的紧迫性、依赖关系、资源可用性、项目关键路径以及潜在风险。通常,在确定任务优先级时,应首先考虑关键路径上的任务,因为这些任务直接影响项目完成的总时长。接着,考虑那些有着严格截止日期或是对项目成败至关重要的任务。资源的分配......
  • 【数据结构多彩画卷】不要只会普通的二叉树了 , 你听说过用二叉树来排序吗? 【二叉搜索
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • 【信奥赛·算法基础】插入排序:算法解析与C++实现
    序言插入排序(InsertionSort)是一种简单的排序算法,就像是我们在打扑克牌时,整理手中牌的过程。一、基本原理插入排序的基本思想是:将待排序的元素插入到已经有序的部分序列中合适的位置,直到所有元素都插入完毕,整个序列就变为有序序列。二、算法步骤从第二个元素开始(假设第......