【C++】STL 算法 ⑥ ( 二元谓词 | std::sort 算法简介 | 为 std::sort 算法设置 二元谓词 排序规则 )

文章目录

  • 一、二元谓词
    • 1、二元谓词简介
    • 2、 std::sort 算法简介
    • 3、 代码示例 - 为 std::sort 算法设置 二元谓词 排序规则





一、二元谓词



1、二元谓词简介


" 谓词 ( Predicate ) " 是一个 返回 布尔 bool 类型值 的 函数对象 / 仿函数 或 Lambda 表达式 / 普通函数 , 可用于对某个条件进行检查 ;

" 谓词 ( Predicate ) " 类型 :

  • 普通函数
  • 函数指针
  • 重载了 函数调用操作符 的 函数对象 / 仿函数 , 有 operator() 函数 ;

" 谓词 ( Predicate ) " 通常被设计成可以接受一定数量的参数

  • 一元谓词 : 接受一个参数
  • 二元谓词 : 接受两个参数

谓词的 函数体 中 根据 传入的 参数 进行计算 , 并返回 true 或 false 布尔值 ;


" 二元谓词 " 就是 接受 两个 参数 的 谓词 ,

" 谓词 " 是 返回 布尔 bool 类型值 的 函数对象 ,

" 函数对象 " 是 重载 函数调用操作符 () 函数 的类 ;


下面的结构体类 函数对象 , 就是一个 " 二元谓词 " , 其作用是将传入的两个 int 参数 , 返回 前者是否比后者大 ;

struct Compare {  bool operator()(int a, int b) const {  return a > b;  }  
};

2、 std::sort 算法简介


C++ 标准模板库 ( STL , Standard Template Library ) 中的 std::sort 算法 是 " 排序算法 ",其底层 算法原理就是 使用 排序算法 对容器中的元素进行排序 , 排序时 根据不同的容器规模 , 自动选择合适的排序算法 , 以提高排序的效率 ;

  • 大型序列 使用 " 快速排序 Quicksort " 算法 ;
  • 小型序列 使用 " 插入排序 Insertion Sort " 算法 ;
  • 递归层次深 的序列 使用 " 堆排序 Heap Sort " 算法 , 避免快排的最坏情况 ;

std::sort 算法 函数原型 :

template <class _RanIt, class _Pr>
void sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred) { // order [_First, _Last), using _Pred_Adl_verify_range(_First, _Last);const auto _UFirst = _Get_unwrapped(_First);const auto _ULast  = _Get_unwrapped(_Last);_Sort_unchecked(_UFirst, _ULast, _ULast - _UFirst, _Pass_fn(_Pred));
}

sort 算法 函数 接受两个迭代器参数 , 这两个 迭代器 定义了一个需要排序的元素范围 , 注意 这是一个 前闭后开区间 [_First, _Last) ;

  • _First 迭代器 指向第一个需要排序的元素 ;
  • _Last 迭代器 指向最后一个元素之后的位置 ;

sort 算法 还可以接受一个 可选 的第三个参数 , 即 比较函数 , 该函数用于定义排序的规则 ;

如果不提供 排序规则 , sort 会 默认使用 operator< 重载操作符函数 对元素进行比较 ;


sort 算法 的 时间复杂度 :最理想的情况下是 O(n log n) , 其中 n 是待排序元素的数 , 这是 " 快速排序 Quicksort " 算法 的时间复杂度 ; 在实际应用场景中 , 排序的性能可能会受到数据分布 , 元素类型以及比较函数的影响 , 如 递归层次比较深 有可能出现极端情况 ;

sort 算法 的 空间复杂度 : sort 算法是一种 原地排序算法 , 该算法不需要额外的存储空间来保存排序结果 ; 而是在输入序列中直接进行排序 ;


std::sort 排序算法 用法示例 :

//函数对象 类重载了()
template <typename T>
class Compare {
public:bool operator()(T& a, T& b) const {return a < b;}
};// 创建一个 vector 单端数组容器
vector<int> vec;// std::sort 排序算法, 默认使用快速排序
sort(vec.begin(), vec.end(), Compare<int>());

3、 代码示例 - 为 std::sort 算法设置 二元谓词 排序规则


在下面的代码中 , 定义了 二元谓词 Compare ;

//函数对象 类重载了()
template <typename T>
class Compare {
public:bool operator()(T& a, T& b) const {return a < b;}
};

在该 二元谓词 的 重载 函数调用操作符 函数中 , 接收 2 个元素 , 返回 第一个元素 是否 小于第二个元素 , 这是进行 从小到大 排序的 规则 ;

然后 , 创建一个 vector 单端数组容器 , 之后将该 容器中的元素进行排序 ;

	// 创建一个 vector 单端数组容器vector<int> vec;

最后 , 调用 sort 排序算法 , 将 vector 容器中的元素进行排序 ;

	// std::sort 排序算法, 默认使用快速排序sort(vec.begin(), vec.end(), Compare<int>());

代码示例 :

#include "iostream"
using namespace std;
#include <vector>
#include <algorithm>
#include "functional"//函数对象 类重载了()
template <typename T>
class Compare {
public:bool operator()(T& a, T& b) const {return a < b;}
};int main() {// 创建一个 vector 单端数组容器vector<int> vec;// 向容器中插入元素vec.push_back(9);vec.push_back(5);vec.push_back(2);vec.push_back(7);// std::sort 排序算法, 默认使用快速排序sort(vec.begin(), vec.end(), Compare<int>());//容器的遍历cout << "遍历容器 :" << endl;for (auto it = vec.begin(); it != vec.end(); it++){cout << *it << " ";}cout << "遍历结束" << endl;// 控制台暂停 , 按任意键继续向后执行system("pause");return 0;
};

执行结果 :

遍历容器 :
2 5 7 9 遍历结束
请按任意键继续. . .

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/329582.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(06)金属布线——为半导体注入生命的连接

01、半导体的核心——“连接” 在上几篇文章中,我们详细讲解了氧化、光刻、刻蚀、沉积等工艺。经过上述工艺,晶圆表面会形成各种半导体元件。半导体制造商会让晶圆表面布满晶体管和电容(Capacitor);而代工厂或CPU制造商则会让晶圆底部排列鳍式场效电晶体(FinFET)等三维…

SSD固态硬盘数据修复方案介绍

这么多故障的可能&#xff0c;那么固态硬盘SSD的数据修复&#xff0c;到底是否有办法呢&#xff1f;我们这里介绍两种尝试修复的方式&#xff0c;不能保证一定会成功。在你误删除一些文件的时候&#xff0c;可以尝试下&#xff0c;市场也有也有很多的修复软件。 方式1:采用修复…

最新版付费进群系统源码 /同城定位付费进群源码 /自带定位完整版/后台分销站点

源码介绍&#xff1a; 最新版付费进群系统源码 &#xff0c;它是同城定位付费进群源码&#xff0c;而且自带定位完整版和后台分销站点。 看到有些人分享一些虚假的内容或者缺少文件的内容。现在分享完整给大家&#xff0c;功能是完整的。它是同城定位付费进群源码。 功能&am…

在Raspberry Pi Zero W中配置TFT LCD Framebuffer驱动

TFT LCD Framebuffer驱动配置 文章目录 TFT LCD Framebuffer驱动配置1、硬件准备2、软件配置2.1 启用SPI驱动2.2 TFT LCD设备驱动树配置 本文将以ILI9341 LCD为例&#xff0c;将详细介绍如何配置TFT LCD的Framebuffer驱动。 1、硬件准备 Raspberry Pi Zero W开发板一个&#x…

修改Gitee用户名

首先进入首页&#xff0c;点击右上角下拉列表中的账号设置 只想改姓名的话&#xff0c;就只要改下下面这里 还想把个人空间地址改了的话还要改下面这里

java基于SSM的二手交易平台设计与开发论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本二手交易平台就是在这样的大环境下诞生&#xff0c;其可以帮助使用者在短时间内处理完毕庞大的数据信息&am…

智慧医院预约及支付平台—智慧支付

医保支付流程 自费支付流程 智慧医院支付业务介绍 社保卡绑定(身份认证) 认证方案:银行身份已验证客户,可通过本人银行登记的手机号码登录医院APP后,在完善APP注册身份信息时,将相关信息发送苏州银行,由银行核对客户身份信息正确性并将社保卡绑定本人手机。核实后的身份…

2024阿里云优惠活动有哪些?

2024年阿里云优惠活动大全&#xff0c;包括阿里云服务器优惠活动清单、配置价格表、域名优惠活动、阿里云建站活动、阿里云优惠代金券免费领取、对象存储OSS活动、企业邮箱优惠、无影云电脑优惠、CDN特惠等等&#xff0c;阿里云百科aliyunbaike.com分享2024阿里云优惠活动大全_…

解决ImportError: Failed to import test module: sys.__init__

解决ImportError: Failed to import test module: sys.init 背景 学习通过文件夹执行测试脚本时&#xff0c;出现了错误&#xff1a;ImportError: Failed to import test module: sys.__init__ 解决过程 根据报错信息&#xff1a;sys is not a package大胆猜测可能是文件名…

算法第十三天-组合总和Ⅱ

组合总和Ⅱ 题目要求 解题思路 按顺序搜索&#xff0c;设置合理的变量&#xff0c;在搜索的过程中判断是否会出现重复集结果。重点理解对输入数组排序的作用和参考代码中 大剪枝和小剪枝 的意思 这道题域上一问的区别在于&#xff1a; 第39题&#xff1a;candidates中的数字…

使用ChatGPT生成项目需求文档模板

前言 我们在工作中需要编写的技术文档有多种形式&#xff0c;包括Word、Excel、PDF及一些在线形式。我们可以借助ChatGPT生成文本&#xff0c;然而&#xff0c;它不能直接生成Word、Excel、PDF等格式的文档。因此&#xff0c;我们需要利用其他工具来帮助我们生成一些模板&…

JavaScript 中的数组过滤

在构建动态和交互式程序时&#xff0c;您可能需要添加一些交互式功能。例如&#xff0c;用户单击按钮以筛选一长串项目。 您可能还需要处理大量数据&#xff0c;以仅返回与指定条件匹配的项目。 在本文中&#xff0c;您将学习如何使用两种主要方法在 JavaScript 中过滤数组。…