到目前为止,我们已经把主要的排序模板函数讲完了,读者还记得有哪些吗?这里笔者通过表格向读者展示一下,希望读者对这些排序模板函数有基本掌握。

函数名功能
sort对指定范围内的元素进行通用、高效的排序。不保证相等元素的原始相对顺序。通常使用内省排序(快速排序+堆排序),平均和最优时间复杂度为O(N log N)。
stable_sort对指定范围内的元素进行稳定排序。保证相等元素在排序后的相对顺序与其在原始序列中的相对顺序一致。当内存充足时,时间复杂度为O(N log N),否则为O(N log² N)。
partial_sort对指定范围内的元素进行部分排序。它重新排列元素,使得前 M 个元素是整个范围内最小的 M 个元素,并且按升序排列。其余元素(后 N-M 个)的顺序未被指定。时间复杂度约为O(N log M)。
nth_element部分排序算法,但目标与partial_sort不同。它重新排列元素,确保位于第 n 个位置的元素(如果范围完全排序后)就位。同时,所有在它之前的元素都不大于它,所有在它之后的元素都不小于它。但这两个子区间内部并没有排序。时间复杂度为O(N)。


我们首先需要会排序,其次才能判断一个序列是否为排序序列。本节我们开始学习is_sorted()模板函数,"sorted"意为排好序的,这里is_sorted()的功能是判断一个区间是否为符合规则的排序序列,有返回值,类型是bool值。

使用is_sorted()模板函数时需要确保容器为前向迭代器,也就是只要属于非无序关联式容器都能使用,同时在使用时需要确保包含头文件<algorithm>。

is_sorted(beg , end)有两个重载函数,下面我们通过代码向读者简要展示其参数和功能:


 /*此处检测排序区间为[beg,end),函数有返回值&&数据类型为bool*/ 
   is_sorted(beg , end);//区间是否满足升序排序
   is_sorted(beg , end , cmp());//区间是否满足自定义排序

我们通过is_sorted()来判断一个区间是否为符合规则的排序序列。


#include<iostream>
#include<vector>
#include<string>
#include<functional>//直接使用函数对象库 
#include<iterator> //使用迭代器函数进行切割,复习前面知识 next(it,n) 
#include<algorithm>//包含算法头文件!
using namespace std;
/* is_sorted()来判断一个区间是否为符合规则的排序序列 */
void test()
{
vector<int> v{1,2,3,5,4} ;
if(is_sorted(v.begin(),next(v.begin(),3))) 
{
cout << "区间[0,3)为升序区间\n"; 
}
if(is_sorted(next(v.begin(),3),v.end(),greater<int>())) 
{
cout << "区间[3,5)为升序区间\n"; 
}
} 
int main(){
system("title dotcpp.com");
    test();
    return 0;
}

编译结果如下:

is_sorted()

总共两条输出结果,对于{1,2,3,5,4},[0,3)是升序区间,[3,5)是降序区间,我们通过is_sorted(beg , end)来判断升序区间,通过greater<int>()仿函数重写规则来判断降序区间,皆都能输出,完全符合预给指令。

判断一个区间是否为有序区间就是这么方便!

这里,笔者再教大家一个模板函数——is_sorted_until()。”until“意为”到···为止“,该函数的功能是判断一个区间到哪个位置时不满足排序,会返回第一个不满足排序规则的元素的迭代器;整个区间全部有序排列,则返回end()迭代器。比如存vector容器里的{1,2,3,5,4},我们使用is_sorted_until(),它会返回指向第5个元素的迭代器。同理于is_sorted(),is_sorted_until()模板函数时需要确保容器为前向迭代器,也就是只要属于非无序关联式容器都能使用,同时在使用时需要确保包含头文件<algorithm>。

is_sorted_until(beg , end)有两个重载函数,下面我们通过代码向读者简要展示其参数和功能:



/*检测此区间[beg,end),返回第一个不满足排序规则的迭代器;若为有序序列,则返回end()*/ 
   is_sorted_until(beg , end);//默认升序排序
   is_sorted_until(beg , end , cmp());//自定义排序

我们通过is_sorted_until()来寻找指定区间中是哪个元素中断了排序秩序。


#include<iostream>
#include<vector>
#include<string>
#include<functional>//直接使用函数对象库 
#include<iterator> //使用迭代器函数进行切割,复习前面知识 next(it,n) 
#include<algorithm>//包含算法头文件!
using namespace std;
/* is_sorted_until()来寻找指定区间中是哪个元素中断了排序秩序 */
void test()
{
vector<int> v{1,2,3,5,4} ;
cout << "升序规则,对于序列{1,2,3,5,4}来说,第一个破坏秩序的元素是:【" << *is_sorted_until(v.begin(),v.end()) << "】\n" ;
cout << "降序规则,对于序列{1,2,3,5,4}的区间[3,5)来说,第一个破坏秩序的元素是:【" << ((is_sorted_until(next(v.begin(),3),v.end(),greater<int>())==v.end())?"返回end()":"该结果不会输出的!") << "】\n" ;
} 
int main(){
system("title dotcpp.com");
    test();
    return 0;
}

编译结果如下:

is_sorted_until()

总共两条输出,一个是找到了破坏升序序列的"4",一个是对指定区间进行降序规则判断,发现该区间为完全降序区间,所以返回v.end(),输出完全按照指令行事。

总结:本节主要教会读者如何判断一个区间是否为完全排序区间,以及找出第一个不满足排序区间的元素。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)