欢迎来到 安卓源码空间!
安卓源码空间

                         c++ sort使用,sort 底层实现分析(例题理解)




c++ sort使用,sort 底层实现分析(超详细)



🐧首先讲一下,我是偶然做到一个排序的题目,然后觉得这个题目里使用 c++ sort 使用的非常经典,所以就有了这一篇文章


1.sort 的使用

👌 头文件

#include <algorithm> 

👌 函数参数

sort( 数组首地址,数组结束地址,排序方式) 

👌 使用实例
如果我们要对一个含有十个元素的数组进行排序,根据上面参数的使用,代码如下。

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 10;
int main()
{
    int q[10] = {123,121,1,2,45,-546,-4,84,54,20};// 初始化十个数据的无序数组

    for(int i = 0; i < N; i ++)  cout<<q[i]<<" ";  //输出排序前的样子

    cout<<endl<<endl<<endl;  // 打印多个换行为了让输出结果更加好看

    sort(q, q + N); //调用函数进行排序

    for(int i = 0; i < N; i ++) cout<<q[i]<<" "; //输出排序后的样子

    cout<<endl<<endl<<endl;//同上

    return 0;

}


在这里插入图片描述

👍 注意点
我这里并没有使用第3个参数,来确定它的排序方式,而我们看结果是从小到大。
所以这里得出第一个结论,如果不使用第三个参数的话,默认就是把数据从小到大排好
👍 参数3使用

int cmp(int a, int b) { return a>b;//这里如果是 a>b 就是排降序, a < b 就是排升序 } 

ok,这里把排序调用换成如下

sort(q, q + N,cmp); //调用函数进行排序 

那么排序结果
在这里插入图片描述

2.sort函数参数底层详解

常规使用底层逻辑

在这里插入图片描述

😍我们发现当我们使用 sort(a, a + N) 排序时,按照正常的逻辑,是不是应该把a到 a+N的元素全部排序呢(这里也就是把标红的地方全部排序)?

如果把标红的位置全部排序了,那么会超出我们原来数组 q 的范围

😍所以这里得出结论:
sort 排序是左边闭区间,也就是包含 a 所在元素,右边是开区间,也就是不包含 a+N 这个元素

注意点

这里小小的提一点,因为左闭右开这个特性,在vector容器里使用sort时我们要弄清楚,vector返回尾地址的位置

3.sort的排序方法

对于数据量大的排序,会使用快速排序,当快速排序数据量小于某一个阈值,会转变成插入排序,当递归层次比较深的时候,会采用堆排序

4.sort理解例题

洛谷p1068 分数线划定
这是一道排序的题,这里我给出原题目。

[NOIP2009 普及组] 分数线划定

题目描述

世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才,A 市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。面试分数线根据计划录取人数的 150 % 150\% 150% 划定,即如果计划录取 m m m 名志愿者,则面试分数线为排名第 m × 150 % m \times 150\% m×150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。

现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。

输入格式

第一行,两个整数 n , m ( 5 ≤ n ≤ 5000 , 3 ≤ m ≤ n ) n,m(5 \leq n \leq 5000,3 \leq m \leq n) n,m(5n5000,3mn),中间用一个空格隔开,其中 n n n 表示报名参加笔试的选手总数, m m m 表示计划录取的志愿者人数。输入数据保证 m × 150 % m \times 150\% m×150% 向下取整后小于等于 n n n

第二行到第 n + 1 n+1 n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 k ( 1000 ≤ k ≤ 9999 ) k(1000 \leq k \leq 9999) k(1000k9999)和该选手的笔试成绩 s ( 1 ≤ s ≤ 100 ) s(1 \leq s \leq 100) s(1s100)。数据保证选手的报名号各不相同。

输出格式

第一行,有 2 2 2 个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。

从第二行开始,每行包含 2 2 2 个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。

样例 #1

样例输入 #1

6 3 
1000 90 
3239 88 
2390 95 
7231 84 
1005 95 
1001 88

样例输出 #1

88 5 
1005 95 
2390 95 
1000 90 
1001 88 
3239 88

提示

【样例说明】

m × 150 % = 3 × 150 % = 4.5 m \times 150\% = 3 \times150\% = 4.5 m×150%=3×150%=4.5,向下取整后为 4 4 4。保证 4 4 4 个人进入面试的分数线为 88 88 88,但因为 88 88 88 有重分,所以所有成绩大于等于 88 88 88 的选手都可以进入面试,故最终有 5 5 5 个人进入面试。

NOIP 2009 普及组 第二题

解题思路

认真分析题目,其实我们发现,我们只需要先按照两个规则排序
先按分数排序,如果分数一样的话,就按报名号排序。
分数为降序,报名号为升序。

AC代码
#include <bits/stdc++.h>//万能头文件

using namespace std;

const int N = 5e3 + 10;

int sub[N], f, k[N], s[N];

bool cmp(int a, int b)
{
    if(s[a] == s[b]) return k[a] < k[b];//分数相同,按照报名号排升序
    return s[a] > s[b];//分数不同,就按照分数排降序
}

int main()
{
    int n, m;
    scanf("%d %d", &n, &m);

    for(int i = 0; i < n; i ++) cin>> k[sub[i] = i] >> s[i];//输入
    //k数组存放报名号, sub 数组存放下标, s数组存放分数
    

    sort(sub, sub + n, cmp);//其实这里的排序都是对于sub中存放的下标进行排序的

    m = m * 1.5;  // 按照要求向下取整百分之150
    int i;
    for( i = 0; s[sub[i]] >= s[sub[m - 1]]; i++);//统计满足分数线的人数

    cout<<s[sub[m-1]]<<" "<<i<<endl;//按照题目要求输出分数线和人数

    for(i = 0; s[sub[i]] >= s[sub[m-1]]; i++) cout<<k[sub[i]]<<" "<<s[sub[i]]<<endl;
    //最后输处所有进入面试的报名号跟分数
    return 0;
}
 

如果这里题解看不懂,可以去洛谷上面看。

5.以上的一部分是我看了两位大佬写的sort,然后自己思考总结合成的,这里附上原文链接,请两位大佬不要在乎我的搬运。

c++ sort 底层
sort 底层排序逻辑

每日语录

少年没有乌托邦,心向远方自明朗!


请添加图片描述


————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                        
                            原文链接:https://blog.csdn.net/qq_61715584/article/details/128174161

copyright@ 2020-2028  安卓源码空间网版权所有   

备案号:豫ICP备2023034476号-1号