list从0到1的突破

目录

前言

1.list的介绍

2.list的常见接口

2.1 构造函数( (constructor))  +接口说明    

2.2 list iterator 的使用

 2.3 list capacity

2.4 list element access

2.5 list modifiers

3.list的迭代器失效

附整套练习源码

结束语


前言

前面我们学习了vector,本节我们将对新的容器list进行拆分学习,并且有了string和vector的基础,list容器的方法学习起来就会轻松很多。

1.list的介绍

 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。

2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。

3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高 效。

4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。

5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间 开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)

2.list的常见接口

2.1 构造函数( (constructor))  +接口说明    

list (size_type n, const value_type& val = value_type())     构造的list中包含n个值为val的元素

list()         拷贝空的list

list (const list& x)     拷贝构造函数

list (InputIterator first, InputIterator last)      用[first, last)区间中的元素构造list

void test1() {list<int>l1;list<int>l2(5, 10);list<int>l3(l2.begin(), l2.end());//迭代器构造list<int>l4(l2);//拷贝构造//以数组区间迭代器构造listfloat arr[] = { 5.20,13.14,9.99,8.88 };list<float>l5(arr, arr + sizeof(arr) / sizeof(float));// 列表格式初始化C++11list<int> l6{ 1,2,3,4,5 };// 用迭代器方式打印l5中的元素list<float> ::iterator it = l5.begin();while (it != l5.end()) {cout << *it << " ";it++;}cout << endl;// C++11范围for的方式遍历for (auto e : l6) {cout << e << " ";}
}

注意:遍历链表只能用迭代器和范围for

2.2 list iterator 的使用

void TestList2()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));// 使用正向迭代器正向list中的元素// list<int>::iterator it = l.begin();   // C++98中语法auto it = l.begin();                     // C++11之后推荐写法while (it != l.end()){cout << *it << " ";++it;}cout << endl;// 使用反向迭代器逆向打印list中的元素// list<int>::reverse_iterator rit = l.rbegin();auto rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;
}

跟vector几乎是一样的

注意:

1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动 

 2.3 list capacity

2.4 list element access

 官方测试代码展示

list<int> mylist;mylist.push_back(10);while (mylist.back() != 0)
{mylist.push_back(mylist.back() - 1);
}cout << "mylist contains:";
for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;cout << '\n';

 

2.5 list modifiers

push_front    在list首元素前插入值为val的元素       pop_front    删除list中第一个元素 

push_back     在list尾部插入值为val的元素             pop_back删除list中最后一个元素 insert    在list position 位置中插入值为val的元素   erase删除list position位置的元素

swap交换两个list中的元素                                        clear清空list中的有效元素 

void print_list(const list<int>& ml) {// 注意这里调用的是list的 begin() const,返回list的const_iterator对象list<int>::const_iterator it = ml.begin();while (it != ml.end()) {cout << *it << " ";it++;}cout << endl;
}
void TestList3() {list<int>mylist{ 1,2,3,4,5 };mylist.push_back(6);mylist.push_front(0);print_list(mylist);mylist.pop_back();mylist.pop_front();print_list(mylist);
}
void TestList4()
{int array1[] = { 1, 2, 3 };list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));// 获取链表中第二个节点//auto pos = ++L.begin();list<int>::iterator pos = ++L.begin();cout << *pos << endl;// 在pos前插入值为4的元素L.insert(pos, 4);print_list(L);// 在pos前插入5个值为5的元素L.insert(pos, 5, 5);print_list(L);// 在pos前插入[v.begin(), v.end)区间中的元素vector<int> v{ 7, 8, 9 };L.insert(pos, v.begin(), v.end());print_list(L);// 删除pos位置上的元素L.erase(pos);print_list(L);// 删除list中[begin, end)区间中的元素,即删除list中的所有元素L.erase(L.begin(), L.end());print_list(L);
}

 这里我们设置了一个打印链表值的函数,方便打印链表,只是打印整数,想打印其他值可以参考vector建立一个模版打印函数,让编译器自己推测打印数据的类型。

template <class Container>
void print(const Container& v) {auto it = v.begin();while (it != v.end()) {cout << *it << " ";it++;}cout << endl;
}
void TestList5()
{// 用数组来构造listint array1[] = { 1, 2, 3 ,4 ,5};list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));print_list(l1);list<int>l2{ 6,7,8,9,10 };// 交换l1和l2中的元素l1.swap(l2);print_list(l1);print_list(l2);// 将l2中的元素清空l2.clear();cout << l2.size() << endl;
}

3.list的迭代器失效

此处可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节 点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

void TestList() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1 (arr, arr + sizeof(arr) / sizeof(arr[0]));auto it = l1.begin();while (it != l1.end()) {l1.erase(it);it++;}
}

修改后:

void TestList() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1 (arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {//等价于l1.erase(it++);it = l1.erase(it);}print(l1);
}

 变式删除偶数:

void TestList1() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1(arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {if(*it%2==0)it = l1.erase(it);elseit++;}print(l1);
}

附整套练习源码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <list>
#include <vector>
using namespace std;
void test1() {list<int>l1;list<int>l2(5, 10);list<int>l3(l2.begin(), l2.end());//迭代器构造list<int>l4(l2);//拷贝构造//以数组区间迭代器构造listfloat arr[] = { 5.20,13.14,9.99,8.88 };list<float>l5(arr, arr + sizeof(arr) / sizeof(float));// 列表格式初始化C++11list<int> l6{ 1,2,3,4,5 };// 用迭代器方式打印l5中的元素list<float> ::iterator it = l5.begin();while (it != l5.end()) {cout << *it << " ";it++;}cout << endl;// C++11范围for的方式遍历for (auto e : l6) {cout << e << " ";}cout << endl;cout << l5.size() << endl;
}
void TestList2()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));// 使用正向迭代器正向list中的元素// list<int>::iterator it = l.begin();   // C++98中语法auto it = l.begin();                     // C++11之后推荐写法while (it != l.end()){cout << *it << " ";++it;}cout << endl;// 使用反向迭代器逆向打印list中的元素// list<int>::reverse_iterator rit = l.rbegin();auto rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;
}
void test3() {list<int> mylist;mylist.push_back(10);while (mylist.back() != 0){mylist.push_back(mylist.back() - 1);}cout << "mylist contains:";for (list<int>::iterator it = mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;cout << '\n';}
template <class Container>
void print(const Container& v) {auto it = v.begin();while (it != v.end()) {cout << *it << " ";it++;}cout << endl;
}
void print_list(const list<int>& ml) {// 注意这里调用的是list的 begin() const,返回list的const_iterator对象list<int>::const_iterator it = ml.begin();while (it != ml.end()) {cout << *it << " ";it++;}cout << endl;
}
void TestList3() {list<int>mylist{ 1,2,3,4,5 };mylist.push_back(6);mylist.push_front(0);print_list(mylist);mylist.pop_back();mylist.pop_front();print_list(mylist);
}
void TestList4()
{int array1[] = { 1, 2, 3 };list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));// 获取链表中第二个节点//auto pos = ++L.begin();list<int>::iterator pos = ++L.begin();cout << *pos << endl;// 在pos前插入值为4的元素L.insert(pos, 4);print_list(L);// 在pos前插入5个值为5的元素L.insert(pos, 5, 5);print_list(L);// 在pos前插入[v.begin(), v.end)区间中的元素vector<int> v{ 7, 8, 9 };L.insert(pos, v.begin(), v.end());print_list(L);// 删除pos位置上的元素L.erase(pos);print_list(L);// 删除list中[begin, end)区间中的元素,即删除list中的所有元素L.erase(L.begin(), L.end());print_list(L);
}
void TestList5()
{// 用数组来构造listint array1[] = { 1, 2, 3 ,4 ,5};list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));//print_list(l1);print(l1);list<int>l2{ 6,7,8,9,10 };// 交换l1和l2中的元素l1.swap(l2);//print_list(l1);//print_list(l2);print(l1);print(l2);// 将l2中的元素清空l2.clear();cout << l2.size() << endl;
}
void TestList() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1 (arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {//等价于l1.erase(it++);it = l1.erase(it);}print(l1);
}
void TestList1() {int arr[] = { 1,2,3,4,5,6,7,8,9 };list<int>l1(arr, arr + sizeof(arr) / sizeof(arr[0]));print(l1);auto it = l1.begin();while (it != l1.end()) {if(*it%2==0)it = l1.erase(it);elseit++;}print(l1);
}
int main() {//test3();TestList1();return 0;
}

结束语

本节内容就到此结束啦,相信大家对list有了进一步的了解,下节我们将一步一步实现自己的list!

最后感谢各位友友的支持,给小编点个赞吧!!! 

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

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

相关文章

一款源码阅读的插件

文章目录 进度汇报功能预览添加高亮标记高亮风格设置笔记颜色设置数据概览高亮数据详情 结尾 进度汇报 之前提到最近有在开发一个源码阅读的IDEA插件&#xff0c;第一版已经开发完上传插件市场了&#xff0c;等官方审批通过就可以尝鲜了。插件名称&#xff1a;Mark source cod…

防火墙——NAT

目录 NAT NAT分类 旧分类 新分类 NAT配置 源NAT​编辑 配置源NAT地址池​编辑 关于源NAT环路问题 环境如下​编辑 防火墙nat​编辑​编辑 路由器要配置指向11.0.0.0 网段的静态路由​编辑 测试​编辑 如果此时有外网用户直接pingNAT地址&#xff0c;则环路出现。​…

PAT甲级-1016 Phone Bills

题目 题目大意 顾客打长途电话计费&#xff0c;输出每月的账单。输入一行给出一天24小时的计费钱数&#xff0c;注意单位是美分&#xff0c;还要乘以0.01。接下来给出n条记录&#xff0c;每条记录都包括客户名&#xff0c;时间&#xff0c;状态。“on-line”是开始打电话的时间…

专题四_位运算( >> , << , , | , ^ )_算法详细总结

目录 位运算 常见位运算总结 1.基础位运算 2.给一个数 n ,确定它的二进制表示中的第 x 位是 0 还是 1 3.运算符的优先级 4.将一个数 n 的二进制表示的第 x 位修改成 1 5.将一个数n的二进制表示的第x位修改成0 6.位图的思想 7.提取一个数&#xff08;n&#xff09;二进…

如何优雅地处理返回值

我们已经知道了如何优雅的校验传入的参数了&#xff0c;那么后端服务器如何实现把数据返回给前端呢&#xff1f; 返回格式 后端返回给前端我们一般用 JSON 体方式&#xff0c;定义如下&#xff1a; {#返回状态码code:string, #返回信息描述message:string,#返回值data…

算法设计与分析(线性时间选择算法

目录 线性时间选择算法&#xff08;QuickSelect&#xff09;实现注意事项有可能出现的特殊情况&#xff1a;小结&#xff1a; 线性时间选择算法&#xff08;QuickSelect&#xff09;实现 线性时间选择算法 是快速排序算法的一个变种&#xff0c;用于在未完全排序的数组中找到第…

Next-ViT: 下一代视觉Transformer,用于现实工业场景中的高效部署

摘要 由于复杂的注意力机制和模型设计&#xff0c;大多数现有的视觉Transformer&#xff08;ViTs&#xff09;在实际的工业部署场景中&#xff0c;如TensorRT和CoreML&#xff0c;无法像卷积神经网络&#xff08;CNNs&#xff09;那样高效运行。这提出了一个明显的挑战&#x…

[Redis] Redis中的set和zset类型

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

微信,手机文件管理,通过自己软件打开——手机平板电脑编程———未来之窗行业应用跨平台架构

一、手机平板IT人员编程编辑器 专为 IT 和运维人员设计的手机和平板编程编辑器&#xff0c;具有便携灵活、即时响应、适应多场景、触控便捷、资源丰富、成本较低、激发创意和数据同步方便等优点。 二、手机平板现状 目前手机和平板的现状是缺乏专门针对 IT 人员的编辑工具&a…

避免服务器安装多个mysql引起冲突的安装方法

最近工作中涉及到了数据迁移的工作. 需要升级mysql版本到8.4.2为了避免升级后服务出现异常, 因此需要保留原来的mysql,所以会出现一台服务器上运行两个mysql的情况 mysql并不陌生, 但是安装不当很容易引起服务配置文件的冲突,导致服务不可用, 今天就来介绍一种可以完美避免冲突…

COMDEL电源CX2500S RF13.56MHZ RF GENERATOR手侧

COMDEL电源CX2500S RF13.56MHZ RF GENERATOR手侧

【C++ Primer Plus习题】16.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream> #include <list> using …

采用 Redis+数据库为某互联网文化公司建立网上社区平台

目录 案例 【说明】 【问题 1】(10 分) 【问题 2】(7 分) 【问题 3】(8 分) 【答案】 【问题 1】解析 【问题 3】解析 相关推荐 案例 阅读以下关于数据库缓存的叙述&#xff0c;回答问题 1 至问题 3。 【说明】 某互联网文化发展公司因业务发展&#xff0c;需要建立网…

海思Hi3559av100 sdk开发环境搭建

SDK阐释 海思官方给的sdk布局&#xff0c;如Hi3559AV100R001C02SPC031&#xff0c;其包含编译工具、硬件设计资料、软件sdk、文档等资料&#xff0c;tree布局可以构建如下形式&#xff0c;但不是必要的。 软件sdk在 01.software中&#xff0c;这个路径下才是真正的软件代码&…

嵌入式DCMI摄像头功能调试方法

STM32F407芯片带有DCMI接口,在我们的核心板上已经将接口用18PIN的FPC座子引出。 这个接口可以接我们的OV2640接口。 本节我们开始调试摄像头。 16.1. DCMI DCMI接口是ST自己定义的接口。 Digital camera interface (DCMI),是意法半导体公司产品STM32F4xx系列芯片的快速摄像头…

Redis 篇-初步了解 Redis 持久化、Redis 主从集群、Redis 哨兵集群、Redis 分片集群

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 分布式缓存概述 2.0 Redis 持久化 2.1 RDB 持久化 2.1.1 RDB 的 fork 原理 2.2 AOF 持久化 2.3 RDB 与 AOF 之间的区别 3.0 Redis 主从集群 3.1 搭建主从集群 3.2…

使用Tortoisegit完成基于Git提交日志的代码合并

前言 日常开发中除了分支merge合并外&#xff0c;经常会用cherry-pick&#xff0c;示例&#xff1a;git cherry-pick 29d9493d,如果要进行多次代码的遴选&#xff0c;可以借助git工具TortoixeGit&#xff0c;进行多次提交的遴选。 一、Git工具及常用命令 TortoiseGit工具 T…

第二十六篇——九地篇:九种形势的应对之道

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 地势的维度重新阐述了懂得人心的重要性&#xff0c;道久其归一为为别人。…

Village Exteriors Kit 中世纪乡村房屋场景模型

此模块化工具包就是你一直在寻找的适合建造所有中世纪幻想村庄和城市建筑所需要的工具包。 皇家园区 - 村庄外饰套件的模型和纹理插件资源包 酒馆和客栈、魔法商店、市政大厅、公会大厅、布莱克史密斯锻造厂、百货商店、珠宝商店、药店、草药师、银行、铠甲、弗莱切、马厩、桌…

【 html+css 绚丽Loading 】000051 方寸轮回矩

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f…