C++从入门到起飞之——list使用 全方位剖析!

 

🌈个人主页:秋风起,再归来~
🔥系列专栏:C++从入门到起飞          
🔖克心守己,律己则安

目录

1、迭代器

2、push_back与emplace_back

3、list成员函数sort与库sort比较

4、merge

5、unique

6、splice 

7、完结散花


前置声明:本文章对于list常用简单的接口不会介绍!

1、迭代器

假如我们想要在list的正向迭代器后的第三位置插入一个2,在上面的这种写法就不再支持了!而我们之前在string和vector的使用时这样玩是完全没有问题的!那是为什么呢!

通过查阅文档资料,我们可以发

现在list下的的迭代器是bidirectional iterator(双向迭代器)

那双向迭代器又是什么意思呢?下面我就和大家总结一下迭代器从功能和性质上的分类:
>从功能上可分为以下四种:

1、正向迭代器

2、反向迭代器

3、正向常量迭代器

4、反向常量迭代器

所有容器的迭代器都具有以上四种功能,用起来也比较简单。

>从性质上可分为以下四种:

1、随机迭代器(RandomAccessIterator):string、vector、deque……(支持操作++ /-- / + / -)

2、双向迭代器(BidirectionalIterator):list、map、set……(支持操作++ /-- )

3、单向迭代器:forward_list、unordered_map……(支持操作++)

容器间迭代器性质上的差异是由容器的底层结构来决定的!而底层结构又决定容器可以使用库里面哪些算法

举个栗子:

list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
sort(lt.begin(), lt.end());

这段代码在编译上并没有报错,不过在运行时就有问题了!

查看资料我们就可以发现问题所在:

我们可以看到,库里面Sort的参数必须是随机的迭代器,因为该Sort的底层是快排,涉及到了迭代器的+和-的操作。

我们还可以注意到第三个参数comp,这其实是一个比较器。这里只演示一下比较器的用法,其底层后面会详细讲解!

vector<int> v;
v.push_back(3);
v.push_back(4);
v.push_back(1);
v.push_back(7);
v.push_back(5);
for (auto e : v)
{cout << e << " ";
}
cout << endl;
sort(v.begin(), v.end());
for (auto e : v)
{cout << e << " ";
}
cout << endl;

在默认情况下,Sort是按照从小到大的顺序排列元素的,如果我们想要按从大到小的顺序排列的话,我们就可以再传递一个比较器!

//greater<int> g;
//sort(v.begin(), v.end(),g);  有名对象这里用的有点烦
//这时候用匿名对传递就很香
sort(v.begin(), v.end(), greater<int>());
for (auto e : v)
{cout << e << " ";
}
cout << endl;

当然,也有小的比较器,这里我们还是要知道一下(效果其实和默认的没什么区别)!

>我们再来看看reverse:

要求传双向迭代器,不过我们也要明白这里不仅可以传双向迭代器,也可以传随机迭代器,毕竟随机迭代器是特殊的双向迭代器。

>我们再来看看find:

Find里面可以传递所有类型的迭代器! 

2、push_back与emplace_back

先说结论,push_back与emplace_back的最终效果都是尾插一个元素,不过emplace_back在某些情况下比push_back的效率要更高一些!

下面举一个代码示例:

class A
{
public:A(int a1 = 0, int a2 = 0):_a(a1), _b(a2){cout << "A(int a1 = 0, int a2 = 0)" << endl;}A(const A& aa):_a(aa._a), _b(aa._b){cout << "A(const A& aa)" << endl;}
private:int _a;int _b;
};void test3()
{list<A> lt;A a1(3, 3);lt.push_back(a1);//有名对象传参lt.push_back(A(2,2));//匿名对象传参//lt.push_back(3,3);  报错!A a2(3, 3);lt.emplace_back(a2);lt.emplace_back(A(2, 2));cout << endl;lt.emplace_back(3,3);//emplace_back还支持直接传递构造A对象的参数!

那emplece_back到底高效在哪些地方呢?

通过函数调用在屏幕上打印的结果我们发现,前面的传参都是构造加拷贝构造,唯有最后的传参是直接调用构造而并没有调用拷贝构造。这说明emplace_back的直接传递构造对象的参数是可以减少拷贝构造的,这也在一定程度上提高了效率。

至于其底层原理还不是我们目前可以明白的,以后我们再细说啦~

3、list成员函数sort与库sort比较

由于不能直接使用库里面的sort,所以list自己实现了一个sout(底层实际上用的是归并)

 下面我们来比较一下在相同数据情况下vector调库里面的sortlist调自己的sort性能之间的优劣

srand((unsigned int)time(nullptr));
const int N = 1000000;list<int> lt1;
vector<int> v;for (int i = 0; i < N; ++i)
{auto e = rand() + i;lt1.push_back(e);v.push_back(e);
}int begin1 = clock();
// 排序
sort(v.begin(), v.end());
int end1 = clock();int begin2 = clock();
lt1.sort();
int end2 = clock();printf("vector sort:%d\n", end1 - begin1);
printf("list sort:%d\n", end2 - begin2);

 在debug模式下,库里面的sort略胜一筹

release模式下速度是list的将近4倍! 

>下面我们再来看一段更有意思的比较

下面这段代码主要的意思我们先在lt1和lt2中存储相同的数据,我们再分别计算两段时间进行比较!

第一段计算的时间是我们先把lt1中的数据拷贝到v中,在通过v调用库里面的sort来排序,最后再从v中将有序的数据拷贝回lt1中。

第二段计算的时间是我们直接通过lt2调用自己的sort来将数据进行排序!

void test_op2()
{srand(time(0));const int N = 1000000;list<int> lt1;list<int> lt2;for (int i = 0; i < N; ++i){auto e = rand() + i;lt1.push_back(e);lt2.push_back(e);}int begin1 = clock();// 拷贝vectorvector<int> v(lt2.begin(), lt2.end());// 排序sort(v.begin(), v.end());// 拷贝回lt2lt2.assign(v.begin(), v.end());int end1 = clock();int begin2 = clock();lt1.sort();int end2 = clock();printf("list copy vector sort copy list sort:%d\n", end1 - begin1);printf("list sort:%d\n", end2 - begin2);
}

 在debug测试版本下我们相差不多

不过,在release发行版本下,第一段的速度依旧接近你的2倍! 

通过这段测试想要告诉你们的是list内部实现的sort用起来方便,可效率却不高,我们写程序首先要确保层序的正确性,二是要追求程序的高效与安全!我们以后在用list存储数据进行排序时最好不要用它内置的sort,绕一下弯就可以大大提高效率!

4、merge

接口merge的主要功能是合并两个链表(但是要注意其中一个链表会变空,相当于把其中一个链表的节点连接到另一个链表的后面去了!)

std::list<double> first, second;first.push_back(3.1);
first.push_back(2.2);
first.push_back(2.9);second.push_back(3.7);
second.push_back(7.1);
second.push_back(1.4);first.sort();
second.sort();first.merge(second);// (second is now empty)

合并后链表是有序的!

注意:使用该接口时要确保两个链表的数据是有序的并且类型要匹配! 

5、unique

unique是去重算法,使用的前提条件是链表必须有序!

std::list<int> lt;lt.push_back(3);
lt.push_back(1);
lt.push_back(2);
lt.push_back(4);
lt.push_back(4);
lt.push_back(5);
lt.push_back(5);
lt.push_back(5);lt.sort();
lt.unique();

6、splice 

用splice 将lt2的所有元素剪切到 lt.end()前面!

std::list<int> lt;
std::list<int> lt2;lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);lt2.push_back(2);
lt2.push_back(3);
lt2.push_back(4);
lt2.push_back(5);lt.splice(lt.end(),lt2);

 用splice将lt2的第一个元素剪切到 lt.begin()前面!

lt.splice(lt.begin(),lt2,lt2.begin());

还可以将自己的元素进行剪切拼接!

假如我想要将元素5插入到2前面,我们可以这样操作!

std::list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
lt.push_back(6);
auto pos1 = find(lt.begin(), lt.end(), 2);
auto pos2 = find(lt.begin(), lt.end(), 5);
lt.splice(pos1,lt,pos2)

7、完结散花

好了,这期的分享到这里就结束了~

如果这篇博客对你有帮助的话,可以用你们的小手指点一个免费的赞并收藏起来哟~

如果期待博主下期内容的话,可以点点关注,避免找不到我了呢~

我们下期不见不散~~

​​​​​​

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

讨论运维监控工具的普及程度

在讨论运维监控工具的普及程度时&#xff0c;加入PIGOSS BSM产品的分析是非常有意义的&#xff0c;因为PIGOSS BSM是一款在中国市场具有一定影响力的运维监控工具。 PIGOSS BSM运维监控工具是一款综合性的IT运维监控解决方案&#xff0c;它能够对多层次的IT资源进行监测&#x…

MQTT Client源码分析

MQTT Client源码分析 目录 MQTT Client源码分析1. mqttclient架构1.1 API1.2 mqtt_client_t结构体1.3 mqtt_yield_thread内部线程1.4 keepalive1.5 ack链表 2. mqttclient流程2.1 MQTT CONNECT2.2 MQTT SUBSCRIBE2.3 MQTT PUBLISH2.4 接收服务器PUBLISH消息 之前基于杰杰的mqtt…

大数据-118 - Flink DataSet 基本介绍 核心特性 创建、转换、输出等

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

手机怎么把wmv转换成mp4格式?视频格式这样做,让你的视频更加通用

“我最近想在手机上编辑视频&#xff0c;但遇到一个问题&#xff0c;就是我有一些wmv格式的视频&#xff0c;想把它们转换成mp4格式&#xff0c;好把它们发布到平台上。但是我不会转格式。请问手机怎么把wmv转换成mp4格式呢&#xff1f;请大家帮帮我。” 格式转换对于没怎么接…

JAVA 二维码生成

1.pom依赖 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.3.3</version></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>ja…

四川财谷通抖音小店创新引领新风尚

在数字化浪潮的推动下&#xff0c;电商行业蓬勃发展&#xff0c;抖音小店作为新兴的电商平台&#xff0c;凭借其独特的社交属性和便捷的购物体验&#xff0c;迅速赢得了广大消费者的青睐。在众多抖音小店中&#xff0c;四川财谷通抖音小店以其精准定位、高质量内容、一站式服务…

智慧公厕:城市公共卫生管理的新篇章‌@卓振思众

在快节奏的现代生活中&#xff0c;公共厕所作为城市基础设施的重要组成部分&#xff0c;其使用体验和管理效率直接影响着市民的生活质量与城市形象。随着科技的飞速发展&#xff0c;智慧公厕应运而生&#xff0c;它以一种全新的姿态&#xff0c;为城市公共卫生管理带来了前所未…

鸿蒙Harmony--状态变量更改通知--@Watch装饰器详解

风雨飘摇中&#xff0c;我心起伏&#xff0c; 万丈雄心&#xff0c;却难以施展。 天高地远&#xff0c;路途迷茫&#xff0c; 理想如星&#xff0c;却遥不可及。 千百次跌倒&#xff0c;千百次爬起&#xff0c; 在命运的手掌中&#xff0c;挣扎前行。 谁知我心中的热血滚烫&…

向 ADC 模型和 DAC 建模添加低通滤波器

与单音测试信号相比&#xff0c;双音测试信号可提供更多有关 ADC 性能的信息。您的作者的模型与特定 ADC 的制造商模型非常匹配&#xff0c;因此可以方便地运行误码率模拟。该 ADC 恰好具有非常宽的输入带宽。 对于带宽较低的 ADC&#xff0c;添加如图 1 所示的低通滤波器将提…

用亚马逊AI代码开发助手Amazon Q Developer开发小游戏(中篇)

快用人工智能帮程序员写代码、开发游戏&#xff01;今天小李哥就来介绍亚马逊推出的国际前沿人工智能AI代码开发助手Amazon Q Developer。目前该代码助手在Hugging Face代码生成权威测试集SWE-bench中排名第一&#xff0c;可以根据我们的需求生成整个代码项目&#xff0c;并可以…

IDEA莫名奇妙自动选择光标所在行 -罪魁祸首居然是钉钉

请看受害者视角 作为开发者&#xff0c;工作时基本都会运行钉钉吧。最近&#xff0c;钉钉更新了AI功能&#xff0c;但不知道是不是开发团队平时不使用IDE&#xff0c;竟然让这个AI功能影响到了其他软件&#xff0c;简直让人无语。不仅仅是IDEA受影响&#xff0c;就连WebStorm也…

QQ聊天记录删除了怎么恢复?学会这3个方法,简单又有效

QQ作为我们日常沟通的重要工具之一&#xff0c;其聊天记录往往承载着许多珍贵的记忆和重要的信息。但在操作中我们会不小心删除或丢失这些聊天记录&#xff0c;那么QQ聊天记录删除了怎么恢复就成为我们急切需要解决的问题。先别急&#xff0c;本文就为你介绍3种简单又有效的QQ聊…

【Qt笔记】QListWidget控件详解

目录 引言 一、基本概念和特性 二、基本用法 2.1 创建和初始化 2.2 添加和删除项 2.3 选择和遍历项 三、信号与槽 3.1 itemClicked 3.2 itemDoubleClicked 3.3 itemSelectionChanged 四、自定义项 五、排序和查找 六、代码示例 6.1 头文件 6.2 源文件 6.3 主…

腾讯云TRTC无UI集成——分享屏幕主流、辅流(Vue2+JS+TRTC无UI集成)

先阐述一下问题&#xff0c;在项目中用到腾讯云的TRTC&#xff0c;A端发布A1、A2两个视频源&#xff0c;在B端订阅A1、A2使用两个view进行播放渲染 问题主流视频源和辅流视频源渲染在同一view上&#xff0c;控制台报错 // 播放远端视频 TRTCService.js; setRemoteVideo(view)…

【数据结构入门】排序算法之插入排序与选择排序

目录 前言 一、排序的概念及运用 1.排序的概念 2.排序的运用 3.常见排序算法 二、插入排序与选择排序 2.1插入排序 2.1.1直接插入排序 1&#xff09;基本思想 2&#xff09;具体步骤 3&#xff09;算法特性 4&#xff09;算法实现 2.1.2希尔排序 1) 基本思想 2&…

草原灭火车的功能与性能_鼎跃安全

在内蒙古的草原火灾中&#xff0c;水陆两栖全地形草原灭火车曾多次用于紧急救援。其强大的越野能力和高速反应&#xff0c;使其在广袤的草原上能够迅速到达火场&#xff0c;并使用集成的多功能灭火设备进行灭火作业&#xff0c;有效防止了火灾的进一步蔓延。 水陆两栖全地形草原…

React学习-hooks

官方文档&#xff1a;https://zh-hans.react.dev/reference/react/useActionState 1.useEffect(setup, dependencies?) 1.1 基础使用 //hooks import { useEffect } from "react"; import "./App.css";function App(){useEffect(()>{console.log(us…

redis的共享session应用

项目背景&#xff1a; 该项目背景就是黑马的黑马点评项目。 一&#xff1a;基于Session实现验证码登录流程 基本的登录流程我们做了很多了。这个是短信登录流程 其实和普通的登录流程就多了一个生成验证码&#xff0c;并将验证码保存在session中&#xff0c;并且呢&#xf…

vue3中使用supermap icilent3d for cesium

记录从头开始学习supermap icilent3d fro cesium 1.新建vue3项目 npm create vitelatest 添加这个&#xff0c;自动打开浏览器 2.使用supermap icilent3d for Cesium 复制这个Cesium&#xff0c;放到pulibc目录下面 然后分别引入css和js 然后就可以使用了&#xff0c;但是会…

Oracle 客户端 PL/SQL Developer 15.0.4 安装与使用

目录 官网下载与安装 切换中文与注册 连接Oracle数据库 tnsnames.ora 文件使用 Oracle 客户端 PL/SQL Developer 12.0.7 安装、数据导出、Oracle 执行/解释计划、for update。 官网下载与安装 1、官网&#xff1a;https://www.allroundautomations.com/products/pl-sql-d…