当前位置: 首页 > 编程日记 > 正文

C++中std::sort/std::stable_sort/std::partial_sort的区别及使用

某些算法会重排容器中元素的顺序,如std::sort。调用sort会重排输入序列中的元素,使之有序,它默认是利用元素类型的<运算符来实现排序的。也可以重载sort的默认排序,即通过sort的第三个参数,此参数是一个谓词(predicate)。

谓词是一个可调用的表达式,其返回结果是一个能用作条件的值,即返回一个bool类型的值。标准库算法所使用的谓词分为两类:一元谓词(unary predicate,只接受单一参数)和二元谓词(binary predicate,有两个参数)。接受谓词参数的算法对输入序列中的元素调用谓词。因此,元素类型必须能转换为谓词的参数类型。

接受一个二元谓词参数的sort版本用这个谓词代替<来比较元素。

std::sort:对给定区间所有元素进行排序。

std::stable_sort:对给定区间所有元素进行稳定排序,稳定排序算法能够维持相等元素的原有顺序。

std::partial_sort:对给定区间所有元素进行部分排序。

当容器中的元素是一些标准类型(如int、string)时,可以直接使用函数模板。但其元素是自定义类型或者需要按照其它方式排序时,需要自己来实现,有两种方法:一种是自己写比较函数,另一种是重载类型操作符”<”。std::sort/std::stable_sort/std::partial_sort中最后一个参数可以是函数指针类型或函数对象类型。

std::sort采用类似快速排序算法,复杂度为N*log2(N);std::stable_sort采用类似归并排序,复杂度为N*log2(N);std::partial_sort采用类似堆排序,复杂度为N*log(M)。但是在cplusplus中并没有说明每种sort采用的是具体哪种排序算法。

std::sort:Sort elements in range, Sorts the elements in the range [first,last) into ascending order. The elements are compared using operator< for the first version, and comp for the second. Equivalent elements are not guaranteed to keep their original relative order (see stable_sort).

std::stable_sort: Sort elements preserving order of equivalents. Sorts the elements in the range[first,last) into ascending order, like sort, but stable_sort preserves the relative order of the elements with equivalent values.

std::partial_sort:Partially sort elements in range. Rearranges the elements in the range [first,last), in such a way that the elements before middle are the smallest elements in the entire range and are sorted in ascending order, while the remaining elements are left without any specific order.

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "sort1.hpp"
#include <iostream>
#include <algorithm> // std::sort
#include <functional> // std::greater
#include <vector>
#include <array>
#include <string>///
// reference: http://www.cplusplus.com/reference/algorithm/sort/
static bool myfunction(int i, int j) { return (i < j); }static struct myclass {bool operator() (int i, int j) { return (i < j); }
} myobject;int test_sort_1()
{int myints[] { 32, 71, 12, 45, 26, 80, 53, 33 };std::vector<int> myvector(myints, myints + 8);               // 32 71 12 45 26 80 53 33// using default comparison (operator <):std::sort(myvector.begin(), myvector.begin() + 4);           //(12 32 45 71)26 80 53 33// using function as compstd::sort(myvector.begin() + 4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)// using object as compstd::sort(myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)// print out content:std::cout << "myvector contains:";for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';myvector.assign(myints, myints + 8);std::sort(myvector.begin(), myvector.end(), std::greater<int>()); // descending is to use std::greater()std::cout << "myvector contains:";for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';// use std::sort to sort an array in C++11: std::begin/std::endstd::sort(std::begin(myints), std::end(myints));for (int i = 0; i < 8; ++i) {std::cout << " " << myints[i];}std::cout << "\n";return 0;
}/
// reference: https://www.codeproject.com/Articles/38381/STL-Sort-Comparison-Function
class Person_sort4 {
public:// default constructorPerson_sort4() : age(0) {}Person_sort4(int age, std::string name) {this->age = age; this->name = name;}bool operator<(const Person_sort4& rhs) { // define a member < operator for the Person classreturn this->age < rhs.age;}int age;std::string name;
};int test_sort_4()
{std::vector<Person_sort4> vecPerson;vecPerson.push_back(Person_sort4(24, "Calvin"));vecPerson.push_back(Person_sort4(30, "Benny"));vecPerson.push_back(Person_sort4(28, "Alison"));std::sort(vecPerson.begin(), vecPerson.end());for (size_t i = 0; i<vecPerson.size(); ++i)std::cout << vecPerson[i].age << ", " << vecPerson[i].name << std::endl;return 0;
}/
// reference: http://www.cplusplus.com/articles/NhA0RXSz/
struct Person_sort {// Left out making a constructor for simplicity's sake.std::string name;int age;std::string favoriteColor;
};// Sort Container by name function
static bool sortByName(const Person_sort &lhs, const Person_sort &rhs) { return lhs.name < rhs.name; }// Sort Container by age function
static bool sortByAge(const Person_sort &lhs, const Person_sort &rhs) { return lhs.age < rhs.age; }// Sort Container by favorite color
// We can just sort alphabetically and then it will group the color together.
static bool sortByColor(const Person_sort &lhs, const Person_sort &rhs) { return lhs.favoriteColor < rhs.favoriteColor; }// A global const variable to hold how many people to ask for input for.
const unsigned numberOfPeople = 2;int test_sort_2()
{using std::vector;using std::cout;using std::cin;using std::endl;using std::sort;using std::string;// Make a vector that holds 5 blank Person_sort Objectsvector<Person_sort> people { { "Tom", 23, "Red" }, {"Jim", 11, "Green"} };// This will ask for user input to populate the container// with 5 different indivuals.//for (vector<Person_sort>::size_type i = 0; i != numberOfPeople; ++i) {//	cout << "Person_sort #" << i + 1 << " name: ";//	cin >> people[i].name;//	cout << "Person_sort #" << i + 1 << " age: ";//	cin >> people[i].age;//	cout << "Person_sort #" << i + 1 << " favorite color: ";//	cin >> people[i].favoriteColor;//}//cout << "\n\n";// Sort by namesort(people.begin(), people.end(), sortByName);for (Person_sort &n : people)cout << n.name << " ";cout << endl;// Sory by agesort(people.begin(), people.end(), sortByAge);for (Person_sort &n : people)cout << n.age << " ";cout << endl;// Sort by colorsort(people.begin(), people.end(), sortByColor);for (Person_sort &n : people)cout << n.favoriteColor << " ";cout << endl;return 0;
}/
// reference: http://en.cppreference.com/w/cpp/algorithm/sort
int test_sort_3()
{std::array<int, 10> s = { 5, 7, 4, 2, 8, 6, 1, 9, 0, 3 };// sort using the default operator<std::sort(s.begin(), s.end());for (auto a : s) {std::cout << a << " ";}std::cout << '\n';// sort using a standard library compare function objectstd::sort(s.begin(), s.end(), std::greater<int>());for (auto a : s) {std::cout << a << " ";}std::cout << '\n';// sort using a custom function objectstruct {bool operator()(int a, int b) const {return a < b;}} customLess;std::sort(s.begin(), s.end(), customLess);for (auto a : s) {std::cout << a << " ";}std::cout << '\n';// sort using a lambda expression std::sort(s.begin(), s.end(), [](int a, int b) {return b < a;});for (auto a : s) {std::cout << a << " ";}std::cout << '\n';return 0;
}/
// reference: http://www.cplusplus.com/reference/algorithm/stable_sort/
static bool compare_as_ints(double i, double j)
{return (int(i)<int(j));
}int test_stable_sort_1()
{double mydoubles[] { 3.14, 1.41, 2.72, 4.67, 1.73, 1.32, 1.62, 2.58 };std::vector<double> myvector;myvector.assign(mydoubles, mydoubles + 8);std::cout << "using default comparison:";std::stable_sort(myvector.begin(), myvector.end());for (std::vector<double>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';myvector.assign(mydoubles, mydoubles + 8);std::cout << "using 'compare_as_ints' :";std::stable_sort(myvector.begin(), myvector.end(), compare_as_ints);for (std::vector<double>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}/
// reference: http://en.cppreference.com/w/cpp/algorithm/stable_sort
struct Employee_sort {Employee_sort(int age, std::string name) : age(age), name(name) { }int age;std::string name;  // Does not particpate in comparisons
};static bool operator<(const Employee_sort &lhs, const Employee_sort &rhs)
{return lhs.age < rhs.age;
}int test_stable_sort_2()
{std::vector<Employee_sort> v = {Employee_sort(108, "Zaphod"),Employee_sort(32, "Arthur"),Employee_sort(108, "Ford"),};std::stable_sort(v.begin(), v.end());for (const Employee_sort &e : v) {std::cout << e.age << ", " << e.name << '\n';}return 0;
}// reference: http://www.cplusplus.com/reference/algorithm/partial_sort/
int test_partial_sort_1()
{int myints[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };std::vector<int> myvector(myints, myints + 9);// using default comparison (operator <):std::partial_sort(myvector.begin(), myvector.begin() + 5, myvector.end());// using function as compstd::partial_sort(myvector.begin(), myvector.begin() + 5, myvector.end(), myfunction);// print out content:std::cout << "myvector contains:";for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

GitHub: https://github.com/fengbingchun/Messy_Test

相关文章:

阿里云智能 AIoT 首席科学家丁险峰:阿里全面进军IoT这一年 | 问底中国IT技术演进...

作者 | 屠敏受访者 | 丁险峰来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;「忽如一夜春风来&#xff0c;千树万树梨花开。」从概念的流行、至科技巨头的相继入局、再到诸多应用的落地&#xff0c;IoT 的发展终于在万事俱备只欠东风的条件下真正地迎来了属于自己的…

eBCC性能分析最佳实践(1) - 线上lstat, vfs_fstatat 开销高情景分析...

Guide: eBCC性能分析最佳实践&#xff08;0&#xff09; - 开启性能分析新篇章eBCC性能分析最佳实践&#xff08;1&#xff09; - 线上lstat, vfs_fstatat 开销高情景分析eBCC性能分析最佳实践&#xff08;2&#xff09; - 一个简单的eBCC分析网络函数的latency敬请期待...0. I…

spring-data-mongodb必须了解的操作

http://docs.spring.io/spring-data/data-mongo/docs/1.0.0.M5/api/org/springframework/data/mongodb/core/MongoTemplate.html 在线api文档 1关键之识别 KeywordSampleLogical resultGreaterThanfindByAgeGreaterThan(int age){"age" : {"$gt" : age}}Le…

旷视张祥雨:高效轻量级深度模型的研究和实践 | AI ProCon 2019

演讲嘉宾 | 张祥雨&#xff08;旷视研究院主任研究员、基础模型组负责人&#xff09;编辑 | Just出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;基础模型是现代视觉识别系统中一个至关重要的关注点。基础模型的优劣主要从精度、速度或功耗等角度判定&#xff0c;如何…

Python脱产8期 Day02

一 语言分类 机器语言&#xff0c;汇编语言&#xff0c;高级语言&#xff08;编译和解释&#xff09; 二 环境变量 1、配置环境变量不是必须的2、配置环境变量的目的&#xff1a;为终端提供执行环境 三Python代码执行的方式 1交互式&#xff1a;.控制台直接编写运行python代码 …

分别用Eigen和C++(OpenCV)实现图像(矩阵)转置

(1)、标量(scalar)&#xff1a;一个标量就是一个单独的数。(2)、向量(vector)&#xff1a;一个向量是一列数&#xff0c;这些数是有序排列的&#xff0c;通过次序中的索引&#xff0c;可以确定每个单独的数。(3)、矩阵(matrix)&#xff1a;矩阵是一个二维数组&#xff0c;其中的…

Linux基础优化

***************************************************************************************linux系统的优化有很多&#xff0c;我简单阐述下我经常优化的方针&#xff1a;记忆口诀&#xff1a;***********************一清、一精、一增&#xff1b;两优、四设、七其他。*****…

数据集cifar10到Caffe支持的lmdb/leveldb转换的实现

在 http://blog.csdn.net/fengbingchun/article/details/53560637 对数据集cifar10进行过介绍&#xff0c;它是一个普通的物体识别数据集。为了使用Caffe对cifar10数据集进行train&#xff0c;下面实现了将cifar10到lmdb/leveldb的转换实现&#xff1a;#include "funset.h…

计算两个时间的间隔时间是多少

/*** 计算两个时间间隔* param startTime 开始时间* param endTime 结束时间* param type 类型&#xff08;1&#xff1a;相隔小时 2&#xff1a;&#xff09;* return*/public static int compareTime(String startTime, String endTime, int type) {if (endTime nul…

作为西二旗程序员,我是这样学习的.........

作为一名合格的程序员&#xff0c;需要时刻保持对新技术的敏感度&#xff0c;并且要定期更新自己的技能储备&#xff0c;是每个技术人的日常必修课。但要做到这一点&#xff0c;知乎上的网友说最高效的办法竟然是直接跟 BAT 等一线大厂取经。讲真的&#xff0c;BAT大厂的平台是…

2月国内搜索市场:360继续上升 百度下降0.62%

IDC评述网&#xff08;idcps.com&#xff09;03月06日报道&#xff1a;根据CNZZ数据显示&#xff0c;在国内搜索引擎市场中&#xff0c;百度在2014年2月份所占的份额继续被蚕食&#xff0c;环比1月份&#xff0c;下降了0.62%&#xff0c;为60.50%。与此相反&#xff0c;360搜索…

不止于刷榜,三大CV赛事夺冠算法技术的“研”与“用”

&#xff08;由AI科技大本营付费下载自视觉中国&#xff09;整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;在 5 个月时间里&#xff08;5月-9月&#xff09;&#xff0c;创新工场旗下人工智能企业创新奇智连续在世界顶级人脸检测竞赛 WIDER …

Ubuntu14.04上编译指定版本的protobuf源码操作步骤

Google Protobuf的介绍可以参考 http://blog.csdn.net/fengbingchun/article/details/49977903 &#xff0c;这里介绍在Ubuntu14.04上编译安装指定版本的protobuf的操作步骤&#xff0c;这里以2.4.1为例&#xff1a;1&#xff0e; Ubuntu14.04上默认安装的是2.5.0&#xff0c;…

Linux下,各种解压缩命令集合

Linux下&#xff0c;各种解压缩命令集合tar xvfj lichuanhua.tar.bz2tar xvfz lichuanhua.tar.gztar xvfz lichuanhua.tgztar xvf lichuanhua.tarunzip lichuanhua.zip.gz解压 1&#xff1a;gunzip FileName.gz解压 2&#xff1a;gzip -d FileName.gz压缩&#xff1a;gzip File…

gtest使用初级指南

之前在 http://blog.csdn.net/fengbingchun/article/details/39667571 中对google的开源库gtest进行过介绍&#xff0c;现在看那篇博文&#xff0c;感觉有些没有说清楚&#xff0c;这里再进行总结下&#xff1a;Google Test是Google的开源C单元测试框架&#xff0c;简称gtest。…

iOS视频流采集概述(AVCaptureSession)

需求&#xff1a;需要采集到视频帧数据从而可以进行一系列处理(如: 裁剪&#xff0c;旋转&#xff0c;美颜&#xff0c;特效....). 所以,必须采集到视频帧数据. 阅读前提: 使用AVFoundation框架采集音视频帧数据GitHub地址(附代码) : iOS视频流采集概述 简书地址 : iOS视频流采…

300秒搞定第一超算1万年的计算量,量子霸权时代已来?

&#xff08;由AI科技大本营付费下载自视觉中国&#xff09;作者 | 马超责编 | 郭芮来源 | CSDN 博客近日&#xff0c;美国航天局&#xff08;NASA&#xff09;发布了一篇名为《Quantum Supremacy Using a Programmable Superconducting Processor》的报道&#xff0c;称谷歌的…

2014-3-6 星期四 [第一天执行分析]

昨日进度&#xff1a; [毛思想]&#xff1a;看测控技术量待定 --> [良]超额完成&#xff0c;昨天基本上把测控看了一大半啦 [汇编]&#xff1a;认真听课&#xff0c;边听边消化自学 --> [中]基本满足&#xff0c;还需要抽时间总结&#xff0c;特别是前面寻址的各种情况…

行列式介绍及Eigen/OpenCV/C++的三种实现

行列式&#xff0c;记作det(A)&#xff0c;是一个将方阵A映射到实数的函数。行列式等于矩阵特征值的乘积。行列式的绝对值可以用来衡量矩阵参与矩阵乘法后空间扩大或者缩小了多少。如果行列式是0&#xff0c;那么空间至少沿着某一维完全收缩了&#xff0c;使其失去了所有的体积…

基于Go的语义解析开源库FMR,“屠榜”模型外的NLP利器

&#xff08;由AI科技大本营付费下载自视觉中国&#xff09;作者 | 刘占亮 一览群智技术副总裁编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;如何合理地表示语言的内在意义&#xff1f;这是自然语言处理业界中长久以来悬而未决的一个命题。在…

【高级数据类型2】- 10. 接口

2019独角兽企业重金招聘Python工程师标准>>> Go语言-接口 在Go语言中&#xff0c;一个接口类型总是代表着某一种类型&#xff08;即所有实现它的类型&#xff09;的行为。一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干…

Linux软件包命令

2019独角兽企业重金招聘Python工程师标准>>> dpkg命令&#xff1a; dpkg -i **/**.deb 安装软件 dpkg -x **.deb 解开.deb文件 dpkg -r /-p 删除并清配置 更详细的 用dpkg --help 查询 如下&#xff1a; dpkg -i|--install <.deb 文件的文件名> ... | -R|--re…

Caffe中计算图像均值的实现(cifar10)

在深度学习中&#xff0c;在进行test时经常会减去train数据集的图像均值&#xff0c;这样做的好处是&#xff1a;属于数据预处理中的数据归一化&#xff0c;降低数据间相似性&#xff0c;可以将数值调整到一个合理的范围。以下code是用于计算cifar10中训练集的图像均值&#xf…

阿里云弹性公网IP(EIP)的使用限制

阿里云弹性公网IP&#xff08;EIP&#xff09;是一种可以独立购买和持有的公网IP地址资源&#xff0c;弹性公网IP具有独立购买持有、弹性绑定和配置灵活等优势&#xff0c;但实际使用中弹性公网IP也是有很多限制的&#xff0c;阿里云惠网分享弹性公网IP&#xff08;EIP&#xf…

400名微软员工主动曝光薪资:28万元到228万元不等!

作者 | Dave Gershgorn译者 | 弯月&#xff0c;编辑 | 郭芮来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【导读】近日&#xff0c;近400名微软员工分享了他们的薪酬&#xff08;从4万美元到32万美元不等&#xff0c;约为28万人民币到228万人民币&#xff09;&am…

Extjs:添加查看全部按钮

var grid new Ext.grid.GridPanel({renderTo:tsllb,title:产品成本列表,selModel:csm,height:350,columns:[csm,{header: "编码", dataIndex: "bm", sortable: true,hidden:true},{header: "产品", dataIndex: "cp", sortable: true},…

练手扎实基本功必备:非结构文本特征提取方法

作者 | Dipanjan (DJ) Sarkar编译 | ronghuaiyang来源 | AI公园&#xff08;ID:AI_Paradise&#xff09;【导读】本文介绍了一些传统但是被验证是非常有用的&#xff0c;现在都还在用的策略&#xff0c;用来对非结构化的文本数据提取特征。介绍在本文中&#xff0c;我们将研究如…

范数介绍及C++/OpenCV/Eigen的三种实现

有时我们需要衡量一个向量的大小。在机器学习中&#xff0c;我们经常使用被称为范数(norm)的函数衡量向量大小。形式上&#xff0c;Lp范数定义如下&#xff1a;范数(包括Lp范数)是将向量映射到非负值的函数。直观上来说&#xff0c;向量x的范数衡量从原点到点x的距离。更严格地…

js添加网页水印和three.js场景中加水印

我们在日常网页开发的时候&#xff0c;可能想给自己的网页或者canvas里面添加水印&#xff0c;增添个人标记&#xff0c;我这里分为普通静态html页面和threejs中3d场景里面添加水印功能。一 静态html页面添加水印你只需要在你的页面添加一个图片遮罩&#xff0c;通过绝对定位和…

JAVA学习笔记(6)

关于多线程的优先级&#xff0c;这个程序里面&#xff0c;现在计算机比较好&#xff0c;int存储不下了&#xff0c;我跑了好几次都是负分&#xff0c;特把int改成long。但是之后跑出来的结果&#xff0c;两个数字都差不多&#xff0c;不知道是什么问题&#xff1f;等待答案中。…