STL各种排序

STL学习之插入排序的STL实现 直接插入排序的C++实现及随机数组的产生方法这是之前的插入排序的例子程序,改用STL实现后暂时并没有体现vector的优势,以下是插入排序的STL实现 #include #include #include #include #include #include using namespace std; // 生成元素为随机数的数组 template void Random(vecto 阅读详情

//By skywind

STL中有多种排序算法,各有各的适用范围,下面听我一一道来:

I、完全排序

  1. sort()

首先要隆重推出的当然是最最常用的sort了,sort有两种形式,第一种形式有两个迭代器参数,构成一个前开后闭的区间,按照元素的 less 关系排序;第二种形式多加一个指定排序准则的谓词。sort基本是最通用的排序函数,它使用快速排序算法,并且在递归过程中,当元素数目小于一个阈值(一般是16,我的试验是24)时,转成直接插入排序。伟大的数学家Knuth已经证明,在平均意义上,快速排序是最快的了;当然,最坏复杂性比较差。sort要求随机迭代器,因此对于很多编译器来说,对于前向迭代器(如list)使用sort是一个编译错误。(不过,在vc2005里面,这个错误信息实在很糟糕)

sort的基本使用方式如下:

PLAIN TEXT

C++:

    1. #include <vector>
    2. #include <algorithm>
    3. #include <functional>
    4. #include <cstdlib>
    5.  
    6. using namespace std;
    7.  
    8. void func1()
    9. {
    10.     vector<int> ar;
    11.     //向数组里面插入一些随机数
    12.     generate_n(back_inserter(ar), 100, rand);
    13.     //按从小到大排序
    14.     sort(ar.begin(), ar.end());
    15. }

经常有人问如何从大到小逆排序,这个其实有很多种方式实现,如下面的例子:

PLAIN TEXT

C++:

    1. void func2()
    2. {
    3.     vector<int> ar;
    4.     //向数组里面插入一些随机数
    5.     generate_n(back_inserter(ar), 100, rand);
    6.  
    7.     //方法1:使用函数作为谓词
    8.     sort(ar.begin(), ar.end(), GreateThan);
    9.     //方法2:使用仿函数作为谓词
    10.     //注意下面两种方法都需要有个括号,实际上是要产生一个临时对象
    11.     sort(ar.begin(), ar.end(), CompareInt());
    12.     //方法3:使用预定义的Adapter, 定义在 <functional> 中
    13.     sort(ar.begin(), ar.end(), greater<int>());
    14.     //方法4:正常排序,然后翻转过来
    15.     sort(ar.begin(), ar.end());
    16.     reverse(ar.begin(), ar.end());
    17.     //方法5:使用逆迭代器
    18.     sort(ar.rbegin(), ar.rend());
    19. }

最后一种方法是我比较欣赏的,可以不能直接对原生数组使用,也就是说,如果ar的定义是int ar[MAXN],上面其他的排序算法都可以简单的改成sort(ar, ar+MAXN, ...),但最后一个不行,要用另外一种比较丑陋的方式:

PLAIN TEXT

C++:

    1. #include <iterator>
    2. void func3(){
    3.     int ax[5]={1,3,4,5,2};
    4.     sort(reverse_iterator<int*>(ax+5), reverse_iterator<int*>(ax+0));
    5. }
  1. stable_sort

sort优点一大堆,一个缺点就是它不是一种稳定的排序。什么是排序的稳定性?就是如果出现两个元素相等时,要求排序之后他们之间保持原来的次序(比如我们先按学号排序,然后按成绩排序,这时就希望成绩相同的还是按照学号的次序排)。很可惜,快速排序算法就不是稳定的,要追求这个,只好用stable_sort了。

在各种排序算法中,合并排序是稳定的,但一般的合并排序需要额外的O(N)的存储空间,而这个条件不是一定能够满足的(可能是比较奢侈的)。所以在stable_sort内部,首先判断是否有足够的额外空间(如vecotr中的cap()-size()部分),有的话就使用普通合并函数,总的时间复杂性和快速排序一个数量级,都是O(N*logN)。如果没有额外空间,使用了一个merge_without_buffer的关键函数进行就地合并(如何实现是比较有技巧的,完全可以专门谈一谈),这个合并过程不需要额外的存储空间(递归的堆栈除外),但时间复杂度变成O(N*logN),这种情况下,总的stable_sort时间复杂度是O(N*logN*logN)。

总之,stable_sort稍微慢一点儿,但能够保证稳定,使用方法和sort一样。但很多时候可以不用这种方式和这个函数,比如上面的例子,完全可以在排序比较准则中写入成绩和学号两个条件就OK了。

PLAIN TEXT

C++:

    1. class CStudent
    2. {
    3. public:
    4.     CStudent();
    5.     //注意这个比较函数中的const
    6.     bool operator<(const CStudent& rhs) const
    7.     {
    8.         if (m_score != rhs.m_score)
    9.             return (m_score <rhs.m_score);
    10.         return m_name <rhs.m_name;
    11.     }
    12. protected:
    13.     std::string m_name;
    14.     int m_score;
    15. };
    16.  
    17. void func4()
    18. {
    19.     vector<CStudent> arStu;
    20.     sort(arStu.begin(), arStu.end());
    21. }
  1. sort_heap

堆排序也是一种快速的排序算法,复杂度也是O(N*logN)。STL中有一些和堆相关的函数,能够构造堆,如果在构造好的堆上每次取出来根节点放在尾部,所有元素循环一遍,最后的结果也就有序了。这就是sort_heap了。它的使用要求区间已经被构造成堆,如:

PLAIN TEXT

C++:

    1. void func5()
    2. {
    3.     vector<int> ar;
    4.     //生成数据
    5.     generate_n(back_inserter(ar), 100, rand);
    6.     //构造堆
    7.     make_heap(ar.begin(), ar.end());
    8.     //堆排序
    9.     sort_heap(ar.begin(), ar.end());
    10. }
  1. list.sort

对于list容器,是不能直接使用sort的(包括stable_sort),从技术的角度来说,sort要求随机迭代器;从算法的角度来说,list这种链表结构本身就不适合用快速排序。因此,list容器内部实现了专门的sort算法,这个算法采用的是合并排序,应该是稳定的(不确定)。如:

PLAIN TEXT

C++:

    1. list<int> li;
    2.     li.sort();
  1. 其他
    • 优先队列(priority_queue)每次弹出的都是max值。实际上就是heap的一个容器方式的包装。
    • 关联式容器自身就必须是有序的(针对key),对其迭代时,key是递增的。

II、部分排序

这些部分排序功能能够完成一段数据(而不是所有)的排序,在适当的适合使用可以节省计算量。用的人不多,可能了解的也比较少。

  1. partial_sort(), partial_sort_copy()

这两个函数能够将整个区间中给定数目的元素进行排序,也就是说,结果中只有最小的M个元素是有序的。你当然也可以使用sort,区别就在于效率。如果M显著地小于N,时间就比较短;当然M太小了也不好,那还不如挨个找最小值了。

partial_sort接受三个参数,分别是区间的头,中间和结尾。执行后,将前面M(M=中间-头)个元素有序地放在前面,后面的元素肯定是比前面的大,但他们内部的次序没有保证。partial_sort_copy的区别在于把结果放到另外指定的迭代器区间中:

PLAIN TEXT

C++:

    1. void func6()
    2. {
    3.     int ar[12]={69,23,80,42,17,15,26,51,19,12,35,8};
    4.     //只排序前7个数据
    5.     partial_sort(ar, ar+7, ar+12);
    6.     //结果是 8 12 15 17 19 23 26 80 69 51 42 35,后5个数据次序不定,依赖于实现
    7.     vector<int> res(7);
    8.     //前7项排序后放入res
    9.     partial_sort_copy(ar, ar+7, res.begin(), res.end(), greater<int>() );
    10. }

这两个函数的实现使用的是堆的方法,先将前M个元素构造成堆,然后挨个检查后面的元素,看看是否小于堆的最大值,是的话就彼此交换,然后重排堆;最后将前面已经是最小的M个元素构成的堆作一次sort_heap就可以了。算法的复杂度差不多是O(N*logM)

  1. nth_element

这个函数只真正排序出一个元素来,就是第n个。函数有三个迭代器的输入(当然还可以加上一个谓词),执行完毕后,中间位置指向的元素保证和完全排序后这个位置的元素一致,前面区间的元素都小于(精确地说,是不大于)后面区间的元素。

熟悉快速排序的马上就能发现,这实际上是一个按位置划分的算法。STL的规范中要求此函数的平均复杂度是线性的,和快速排序一样,这种算法的最坏复杂度比较差。在一般的实现(如SGI)中,采用三种取1的方法寻找划分元素,最坏复杂度是O(N^N)。虽然理论上有一些算法可以保证最坏线性复杂度,但算法过于复杂,STL一般也不采用。

III、排序辅助功能

  1. partition, stable_partition
  2. merge, inplace_merge

IV、有序区间操作

这个准备单独写一篇

STL容器之字典排序 STL简单用法 在 STL9中对vector 的习惯用法完全不同。我们不是定义一个已知大小的 vector,而是定义一个空 vector   vector v; 我们向 vector 中插入元素,而不再是索引元素,以及向元素赋值,例如 push_back()操作,就是在 vector 的后面插入一个元素,下面的 while 循环从标准输入读入一个字符串序列并每次将一个 阅读详情

相关推荐

STL算法,堆排序

/***************************************** STL-算法--Heap算法 堆排序算法 (heapsort) make_heap()         //把容器内的数据做堆排序 push_heap()         //向堆内放入元素 pop_heap()          //删除堆顶元素 sort_heap()         //把堆

u010949971的博客 1811

STL常用算法——排序算法

合并排序,merge() 函数用于将 2 个有序序列合并为 1 个有序容器,前提是这 2 个有序容器的排序规则相同(要么都是升序,要么都是降序)。并且最终借助该函数获得的新有序容器,其排序规则也和这 2 个有序容器要相同。sort() 函数在对自定义的类对象实现排序时,需要在该类的内部提供移动构造函数和移动赋值运算符。sort():对容器或普通数组中范围内的元素进行排序,默认进行升序排序,也可以自定义排序规则。reverse()函数:将容器指定范围内的元素进行反转。函数原型:该函数有以下两种格式。

万里顾一程的博客 1943

STL源码剖析——list容器的排序算法sort()

由于STL本身的排序算法sort接受的输入迭代器是随机访问迭代器,但是双向list链表容器的访问方式是双向迭代器,因此,不能使用STL本身的排序算法sort,必须自己定义属于自己访问的排序算法。我们从源码的剖析中,可以看到该排序算法思想类似于归并排序。

关注校招求职,微信号:job_campus 9381

STL之算法——排序算法

一:介绍 常用的STL排序算法包括sort,reverse,merge,random_shuffle。 二:sort:对容器内元素进行排序 1.函数原型 sort(iterator begin, iterator end) 默认以升序方式对元素进行排序 sort(iterator begin, iterator end, _Pred) 自定义方式对元素排序 2.操作 #include <iostream> #include <algorithm> #include &

qq_38082979的博客 2072

掌握STL的Vector排序方法

在C++中,vector是一个动态数组容器,它能够根据需要自动地增长和缩减大小。vector位于<vector>头文件中,属于std命名空间。以下是几个vector的基本定义和初始化方式:// 默认初始化,创建了一个空的int型vector// 初始化一个包含10个元素的vector,每个元素初始化为0// 初始化一个包含10个元素的vector,每个元素初始化为1// 使用初始化列表定义并初始化vector逻辑分析:vector。

weixin_35749796的博客 1189

比STL更快的整数排序算法

一个定义了整数排序的工程,相比课本上的要更加高效和简洁

【STL二十】算法——排序操作(sort、stable_sort)_集合操作(merge)

stl算法——排序操作(sort、stable_sort)_集合操作(merge)

junxuezheng的博客 1935

stl常用算法(Algorithms)介绍(stl排序算法、非变序型队列)

算法:用来处理群集内的元素。它们可以出于不同的目的而搜寻,排序,修改,使用那些元素。是一种应用在容器上以各种方法处理其内存的行为或功能,如sort(排序),copy(拷贝)… 算法由模板函数体现,这些函数不是容器类的成员函数,是独立的函数,它们可以用于STL容器,也可以用于普通的C++数组等. 头文件:#include 在STL的泛型算法中有4类基本的算法: 1)变序型队列算法: 可以改变容器内的数据; 2)非变序型队列算法:处理容器内的数据而不改变他们; 3)排序值算法:包涵对容器中的值进行排序和合并的算法,还有二叉搜索算法 ,4)通用数值算法:此种算法不多,涉及到专业

【C++STL】快速排序算法(sort)的原理与使用

`std::sort` 是 C++ 标准库中提供的排序算法,它使用的是一种经典的排序算法——**快速排序**(Quicksort)或者是其变种。 快速排序是一种基于比较的排序算法,通过不断地选择一个基准值(pivot),将待排序序列分割为两个子序列,其中一个子序列的所有元素小于等于基准值,另一个子序列的所有元素大于基准值。然后递归地对两个子序列进行排序,最终得到有序序列。

AAADiao的博客 1万+

VSCode+PlatformIO新建工程卡成狗?3步提速大法实测有效(附镜像源配置)

针对VSCode+PlatformIO新建工程时因依赖下载缓慢导致的加载慢问题,本文提供了三步核心提速方案。通过配置Python环境变量、修改PlatformIO插件设置以使用国内镜像源,并优化pip配置文件,实测可大幅缩短工程创建时间,有效解决创建工程卡顿的痛点。

delta的博客 717

手把手教学,Python 游戏编程之实现飞机大战(含源代码)

我想大家都是有玩过类似飞机大战的射击类游戏,也享受目标被消除通过后带来的愉悦感。那么如果用Python来实现飞机大战游戏?下面就跟大家一起用Python来做一个小游戏,不仅可以从中感受到乐趣,还可以提升自己的能力。

veratata的博客 1万+

STL——排序算法

random_shuffle洗牌算法使用时需要加随机数种子。merge合并两个容器必须是有序序列。容器元素合并,并存储到另一容器中。指定范围内的元素随机调整次序。两个容器必须是有序的。

weixin_64238628的博客 1057

新能源知识库(62)组串式、集中式和高压直挂式

因需多台PCS及独立监控设备,单位功率成本比集中式高15%–20%。高压直挂式因省去变压器,大容量项目成本更低(>5MW时优势显著)。组串式储能、集中式储能和高压直挂式储能是当前主流的三类技术路线,其核心差异源于系统架构和控制逻辑的设计差异。组串式交流侧需变压器升压至10kV/35kV,高压直挂式可直接输出6kV/35kV电压,减少转换损耗。多台小功率PCS并联(每簇独立管理)单台大功率PCS(多簇直流侧并联)环流导致容量衰减(损失5%–8%)无变压器损耗(效率>99%)高压直挂电站(≥10MW)

竹君子之家 1520

排序——基于C++ STL的排序

概述 前面我们介绍了十种排序算法。在实际使用中,我们需要在每道 OI 题目中完成排序算法的具体实现。 C++提供了 STL(标准模板库),在这个模板库中,已经提供了排序相关函数。如下图所示。 下面我们介绍一下 STL 库的 sort()函数使用方法。 STL sort底层实现 STL中的sort不是普通的快排,除了对普通的快速排序进行优化,它还结合了插入排序和堆排序。根据不同的数量级...

努力中的老周的专栏 5597

ESP32-CAM图像糊成马赛克?OV2640参数调优保姆级教程(亮度/对比度/饱和度)

本文提供了一份详细的ESP32-CAM图像调优教程,针对OV2640摄像头常见的图像模糊问题,从分辨率设置、亮度/对比度/饱和度调整到高级寄存器配置,帮助用户优化网页显示画质。通过代码示例和实用技巧,解决马赛克、色彩暗淡等问题,提升摄像头性能。

weixin_30410119的博客 598

100天精通Python(基础篇)——第3天:运算符全解析(算术运算符、比较运算符、逻辑运算符、赋值运算符及其优先级规则)

100天精通Python(基础篇)——第3天:运算符全解析(算术运算符、比较运算符、逻辑运算符、赋值运算符及其优先级规则)

努力让自己发光,对的人才能迎着光而来 14万+

STL库中的排序

1 若需对vectorstringdeque, 或array容器进行全排序,你可选择sort或;2 若只需对vectorstringdeque, 或array容器中取得top n的元素,部分排序是首选.3 若对于vectorstringdeque, 或array容器,你需要找到第n个位置的元素或者你需要得到top n且不关系top n中的内部 顺序,是最 理想的;4 若你需要从标准序列容器或者array中把满足某个条件 或者不满足某个条件的元素分开,你最好使用partition或;5 若使用的。

juebukeni的博客 872

CDR插件开发之CPG插件017 - 在VS2019中实现CPG插件调试(自动写入CPG、自动启动CDR)

在上篇文章中,讲解了图像导出实例:当文档打开后,自动导出当前页面的图像到系统临时文件夹。在代码编写过程中,导出图像路径变量tmpFileName 被修改了很多次,有没有办法实现调试功能,通过控制台打印变量,而不用编译成CPG后再通过消息框来调试?当然是可以的。本篇作为单独篇,以CDR X8版本为例,讲解CPG插件在VS2019中实现调试的具体方法。 工程搭建准备 按照惯例,本篇文章的序号为017,请直接拷贝上一个工程016-export-image(拷贝前最好清理掉 Debug、x64等编译目录..

Zebe 1811

STL排序算法

STL排序算法 STL简介 STL:标准模板库。 包含一些常用的算法如排序查找,还有常用的数据结构如可变长数组,链表,字典等。 使用方便,效率较高 要使用其中的算法,需要#include sort排序 用法一: 对基本数据类型的数组从小到大排序: sort(数组名+n1,数组名+n2); ​ n1和n2都是int类型的表达式,可以包含变量。 ​ 如果n1=0,则+n1可以不写 将数组中下标范围为[n1,n2)的元素从小到大排序。下标为n2的元素不在排序区间内。 例如: int a[]={12,

羽的博客 1365

QT使用libssh2库通过密匙实现sftp协议上传文件

qt下使用libssh2通过密匙连接sftp服务器端

小米的修行之路 948

Linux 4.19、Linux 5.10、Linux 6.1 三个版本详细分析

Linux 4.19发布日期:2018年10月22日LTS 状态:是长期支持版本,官方支持到2024年12月。Linux 5.10发布日期:2020年12月13日LTS 状态:LTS 版本,官方支持到2026年12月。Linux 6.1发布日期:2022年12月11日LTS 状态:不是官方的LTS版本,但通常社区会为新的版本提供一定时间的支持。定位:稳定性和长期支持,广泛应用于多种平台,尤其是嵌入式系统和服务器。主要优势:稳定性高,广泛的硬件支持,核心功能可靠。

小灰灰的博客 5959

C++——STL排序算法介绍

对于程序员来说,数据结构是必修的一门课。从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来。幸运的是这些理论都已经比较成熟,算法也基本固定下来,不需要你再去花费心思去考虑其算法原理,也不用再去验证其准确性。不过,等你开始应用计算机语言来工作的时候,你会发现,面对不同的需求你需要一次又一次去用代码重复实现这些已经成熟的算法,而且会一次又一次陷入一些由于自己疏忽而产生的bug中。这时,你想找一种工具,已经帮你实现这些功能,你想怎么用就怎么用,同时不影响性能。你需要的就是STL

shineHoo的专栏 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

c++ stl 排序_C ++ STL排序功能可对数组或向量进行排序

c++ stl 排序 STL sot功能 (STL sot function) C++ STL has a default sort function which sort an array or vector in increasing order. Normally it uses quick sort which has a worst case time complexity of O(n...

cumt30111的博客 1621

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【STL】排序

因此,如果容器中存储的是自定义的类对象,则该类的内部必须提供移动构造函数和移动赋值运算符。同样,如果选用标准库提供的其它排序规则,元素类型也必须支持该规则底层实现所用的比较运算符。当选用默认的升序排序规则时,容器中存储的元素类型必须支持小于运算符;同样,如果选用标准库提供的其它排序规则,元素类型也必须支持该规则底层实现所用的比较运算符;这种情况下,如果容器中存储的是自定义的类对象,则该类的内部必须拷贝构造函数和赋值运算符的重载。void sort(要排序元素的起始地址,要排序元素的结束地址,比较函数);

qq_45951891的博客 1169

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++STL排序

STL中的排序函数 1.Sort函数 功能:对给定的区间所有元素进行排序 排序算法:快速排序,堆排序,插入排序 快速排序的最优时间复杂度:O(nlogn),最差时间复杂度为:O(n^2) 插入排序的最优时间复杂度:O(N),最差时间复杂度为:O(N^2) 堆排序的最优时间复杂度为:O(nlogn),最差时间复杂度为:O(nlogn) 源码: //1.快速排序 //2.堆排序 //3.插入排序 template <class _RandomAccessIter> i

b711183612的专栏 1440

c++STL之排序函数

STL中封装了许多强大的算法,其中排序算法是重中之重,博主从网上找来一些资料修改了一下供参考。 (转载于http://blog.youkuaiyun.com/bz201/article/details/543001) - STL提供的Sort 算法C++之所以得到这么多人的喜欢,是因为它既具有面向对象的概念,又保持了C语言高效的特点。STL 排序算法同样需要保持高效。因此,对于不同的需求,STL提供的不同

x1074972500的博客 5412
上一篇: 给中国学生的第七封信:21世纪最需要的7种人才
下一篇: js中parseInt函数的解析
programerchen
博客等级 码龄15年 3粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值