[C++初阶]list类的初步理解

一、标准库的list类

list的底层是一个带哨兵位的双向循环链表结构
对比forward_list的单链表结构,list的迭代器是一个双向迭代器
与vector等顺序结构的容器相比,list在任意位置进行插入删除的效率更好,但是不支持任意位置的随机访问
list是一个模板类,在使用的时候我们需要给出元素的类型

使用list类时,需要包含头文件<list>

二、list类的常用接口

1.常用的构造函数

1.默认构造函数,构造一个空的链表

list();

例如:

void test()
{list<int> lt;
}

2.构造一个list对象并用n个val初始化

list(size_type n, const value_type& val =  value_type());

例如:

void test()
{list<int> lt(3, 1);for (auto i : lt){cout << i << " ";}
}

运行结果:

3.list类的拷贝构造函数

list(const list& x); 

例如:

void test()
{list<int> lt(3, 1);list<int> lt1(lt);for (auto i : lt1){cout << i << " ";}
}

运行结果:

4.使用迭代器的初始化构造

Template<class InputIterator>list(InputIterator first, InputIterator last);

例如:

void test()
{list<int> lt(3, 1);list<int> lt1(lt.begin(), lt.end());for (auto i : lt1){cout << i << " ";}
}

运行结果:

2.常用的容量接口

还是老几样,我这里一块讲一讲吧。

1.size,empty,max_size,resize

size:返回链表容器中的元素数。

size_type size() const;

empty:返回列表容器是否为空(即其大小是否为 0)。
(注意:此函数不会以任何方式修改容器。若要清除链表容器的内容,请参阅 list::clear。)

bool empty() const;

max_size(不常用):返回链表容器可以容纳的最大元素数。
(由于已知的系统或库实现限制,这是容器可以达到的最大潜在大小,但绝不能保证容器能够达到该大小:在达到该大小之前,它仍然可能无法在任何时候分配存储。)

size_type max_size() const;

resize:调整容器的大小,使其包含 n 个元素。
如果 n 小于当前容器大小,则内容将减少到其前 n 个元素,删除超出(并销毁它们)的元素。
如果 n 大于当前容器大小,则通过在末尾插入所需数量的元素来扩展内容,以达到 n 的大小。如果指定了 val,则新元素将初始化为 val 的副本,否则,它们将进行值初始化。
(请注意,此函数通过插入或擦除容器中的元素来更改容器的实际内容。)

void resize (size_type n, value_type val = value_type());

例如:

​
void test()
{list<int> lt(3, 1);/*list<int> lt1(lt);*/list<int> lt1(lt.begin(), lt.end());list<int> lt2;cout << lt1.size() <<endl;cout << lt1.empty() <<endl;cout << lt2.empty() <<endl;lt1.resize(10);cout << lt1.size() << endl;for (auto i : lt1){cout << i << " ";}
}​

运行结果:

3. 常用的访问与遍历

1.迭代器

iterator begin();const_iterator begin() const;iterator end();const_iterator end() const;

迭代器:用于获取链表中第一个节点的位置和最后一个节点的下一个位置(即哨兵位)

例如:

void test()
{list<int> lt(5, 2);list<int> ::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}
}

运行结果:

2.反向迭代器

reverse_iterator rbegin();

const_reverse_iterator rbegin() const;

reverse_iterator rend();

const_reverse_iterator rend() const;

反向迭代器,rbegin获取容器中最后一个节点的位置,rend获取容器中哨兵位的位置

void test()
{list<int> lt = { 1,23,4,4,5,2 };list<int> ::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}
}

运行结果:

注意:反向迭代器rit也要用++而不是--

3.front和back

front:

reference front();

const_reference front() const;

返回链表中第一个节点存储的数据的引用

back:

reference back();

const_reference back() const;

返回链表中最后一个节点存储的数据的引用

例如:

void test()
{list<int> lt = {213123,123,34524,213};cout << lt.front() << endl;cout << lt.back() << endl;}

运行结果:

4.list的增删查改

1)push_front和pop_front

push_front叫头插,从链表头部插入一个元素

void push_front(const value_type& val);

pop_front叫头删,从链表头部删除一个元素

void pop_front();

void pop_front();

例如:

void test()
{list<int> lt = {213123,123,34524,213};cout << lt.front() << endl;lt.push_front(21345);cout << lt.front() << endl;lt.pop_front();cout << lt.front() << endl;
}

运行结果:

2) push_back和pop_back

push_back叫尾插,从链表尾部插入一个元素

void push_back(const value_type& val);

pop_back叫尾删,从链表尾部删除一个元素

void pop_back();

例如:

void test()
{list<int> lt = {213123,123,34524,213};cout << lt.back() << endl;lt.push_back(21345);cout << lt.back() << endl;lt.pop_back();cout << lt.back() << endl;
}

运行结果:

3) find

template <class InputIterator, class T>InputIterator find(InputIterator first, InputIterator last, const T& val);

在两个迭代器区间寻找val并返回其所在处的迭代器

例如:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 1);*pos = 114514;for (auto i : lt){cout << i << " ";}
}

运行结果:

注意:该函数并非list的成员函数,是标准库中的函数,多个容器共用该find函数

可以看到,我们可以直接对list的迭代器进行解引用并修改其内容,但是迭代器不应该指向节点吗?为什么对其解引用能修改数据呢?

实际上list的迭代器并不是用原生态指针进行模拟实现的,需要进行底层的封装,这里会在list的模拟实现的源代码中体现。

4)insert

iterator insert(iterator position, const value_type& val);

void insert(iterator position, size_type n, const value_type& val);

————————————————————————————————————————

template<class InputIterator>

void insert(iterator position, InputIterator first, InputIterator last);

在position位置的前面插入一个或多个元素

例如:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 1);lt.insert(pos, 8848);for (auto i : lt){cout << i << " ";}
}

运行结果:

细心的同学可能已经发现了,list的insert操作是不会导致迭代器失效的,因为pos指向的节点不变,相对位置也不变。

但是list的删除操作一定会导致迭代器失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

5) erase

iterator erase(iterator position);iterator erase(iterator first, iterator last);

删除position位置的元素或者 [first,last) 区间的所有元素

例如:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 1);lt.erase(lt.begin());for (auto i : lt){cout << i << " ";}
}

运行结果:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 2);lt.erase(lt.begin(),pos);for (auto i : lt){cout << i << " ";}
}

运行结果:

6) swap

void swap(vector& x);

交换两个list对象

例如:

void test()
{list<int> lt;list<int> lt2(6, 12);for (int i = 0; i < 10; i++){lt.push_back(i);}lt.swap(lt2);for (auto i : lt2){cout << i << " ";}cout << endl;
}

运行结果:

7)assign

template <class InputIterator>

void assign(InputIterator first, InputIterator last);

void assign(size_type n, const value_type& val);

为list指定新内容,替换其当前内容并修改节点个数

例如:

void test()
{list<int> lt;for (int i = 0; i < 10; i++){lt.push_back(i);}lt.assign(4, 0);for (auto i : lt){cout << i << " ";}
}

运行结果:

8)clear

void clear();

删除链表所有节点

例如:

void test()
{list<int> lt;for (int i = 0; i < 10; i++){lt.push_back(i);}lt.clear();cout << lt.size() << endl;
}

运行结果:

5.list的顺序修改接口

(1)sort

void sort();

template<class Compare>

void sort(Compare comp);

list由于结构的特殊性,是无法使用标准库中的sort函数的,因为迭代器无法进行相减的操作

并且在C++文档中,我们可以看到标准库中的sort也限定了迭代器的类型必须是可以进行随机访问(RandomAccess)的

default (1)	
template <class RandomAccessIterator>void sort (RandomAccessIterator first, RandomAccessIterator last);
custom (2)	
template <class RandomAccessIterator, class Compare>void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

迭代器有几个功能分类:

  • 单向迭代器,只能进行++
  • 双向迭代器,可以++和--
  • 随机迭代器,可以++,--,+和-

但是list的sort函数也是没什么必要的,因为直接对链表排序的效率比拷贝到vector进行排序再拷贝回链表要慢的多。

(2)reverse

template <class BidirectionalIterator>void reverse (BidirectionalIterator first, BidirectionalIterator last);

对链表进行逆置

例如:

void test()
{list<int> lt;for (int i = 0; i < 10; i++){lt.push_back(i);}for (auto i : lt){cout << i << " ";}cout << endl;lt.reverse();for (auto i : lt){cout << i << " ";}cout << endl;}

运行结果:


如有错误,欢迎指正。

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

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

相关文章

mac生成.dmg压缩镜像文件

mac生成.dmg压缩镜像文件 背景准备内容步骤1&#xff0c;找一个文件夹2&#xff0c;制作application替身1&#xff0c;终端方式2&#xff0c;黄金右手方式 3&#xff0c;.app文件放入文件夹4&#xff0c;制作.dmg压缩镜像文件5&#xff0c;安装.dmg 总结 背景 为绕开App Store…

视频融合共享平台视频共享融合赋能平台数字化升级医疗体系

在当前&#xff0c;医疗健康直接关系到国计民生&#xff0c;然而&#xff0c;由于医疗水平和资源分布不均&#xff0c;以及信息系统老化等问题&#xff0c;整体医疗服务能力和水平的提升受到了限制。视频融合云平台作为数字医疗发展的关键推动力量&#xff0c;在医疗领域的广泛…

Docker部署gitlab私有仓库后查看root默认密码以及修改external_url路径和端口的方法

文章目录 1、docker部署最新版gitlab2、进入gitlab容器3、修改路径地址ip和端口4、检验效果 1、docker部署最新版gitlab #docker安装命令 docker run --detach \--name gitlab \--restart always \-p 1080:80 \-p 10443:443 \-p 1022:22 \-v /gitlab/config:/etc/gitlab \-v …

MacOS 开发 — Packages 程序 macOS新版本 演示选项卡无法显示

MacOS 开发 — Packages 程序 macOS新版本 演示选项卡无法显示 问题描述 &#xff1a; 之前写过 Packages 的使用以及如何打包macOS程序。最近更新了新的macOS系统&#xff0c;发现Packages的演示选项卡无法显示&#xff0c;我尝试从新安转了Packages 也是没作用&#xff0c;…

夏令营入门组day1

一. 题目 二. 初步思路 因为是解决区间上的问题&#xff0c;很容易想到用前缀和来解决。前缀和是o ( n ) 的时间复杂度&#xff0c;但后续枚举两个端点要 o ( n^2 )&#xff0c;对于2e10的数据&#xff0c;超时。 for (int i 1; i < n; i )for (int j i; j <n; j ){if…

转录组和基因芯片GSE数据RAW.tar压缩包下载和多样本整合处理教程

转录组和基因芯片GSE数据集的RAW.tar压缩包下载和多样本整合处理教程 GSEXXX_RAW.tar压缩包手动下载解压 前情回顾 关于OmicsTools根据GSE编号自动下载和提取GEO表达数据 根据GSE编号自动下载和提取GEO表达数据的窗口截图 自动下载和提取整理到结果文件 该模块的分析教程 …

天环公益首发原创开发进度网站 带后台

天环公益计划首发原创开发进度网站 带后台 后台地址是&#xff1a;admin.php 后台没有账号密码 这个没有数据库 有能力的可以自己改 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/89520358 更多资源下载&#xff1a;关注我。

区分modbus tcp和tcp/ip

Modbus 对某些人来说&#xff0c;这听起来可能很复杂&#xff0c;也很令人费解&#xff0c;但是一旦你了解了它的工作原理&#xff0c;那就是一个特别简单的过程。MODBUS 这是一种请求和响应协议。MODBUS 主站将发起请求&#xff0c;从站将响应错误或请求信息。这就是 modbus 简…

通俗易懂,幽默诙谐,《IP 核芯志》让逻辑设计思想摆脱枯燥的标签(可下载)

在科技的广袤星空中&#xff0c;数字逻辑设计宛如一颗璀璨的明星&#xff0c;闪耀着智慧与创造的光芒。而在这光芒的深处&#xff0c;IP 核芯则是那关键的能量源泉&#xff0c;驱动着无数创新的浪潮。 《IP 核芯志——数字逻辑设计思想》犹如一座灯塔&#xff0c;照亮了我们在…

Java | Leetcode Java题解之第229题多数元素II

题目&#xff1a; 题解&#xff1a; class Solution {public List<Integer> majorityElement(int[] nums) {HashMap<Integer, Integer> cnt new HashMap<Integer, Integer>();for (int i 0; i < nums.length; i) {if (cnt.containsKey(nums[i])) {cnt.…

Python 核心编程

Python 核心编程 1. 数据类型1.1 整型 int1.2 浮点数 float1.3 布尔类型 bool1.4 字符串 str1.5 列表 list1.6 元组 tuple1.7 集合 set1.8 字典 dict 2. 逻辑结构、文件操作2.1 分支结构和三元表达2.2 循环和遍历2.3 目录和路径2.4 文件操作 3. 函数、类、异常处理3.1 函数3.2 …

JS爬虫实战之极验四代

极验四代滑块验证码 一、目标网站说明二、流程步骤1. 逆向步骤一般分为&#xff1a;2. 接口确认1- 确认流程2- 获取verify的参数3- 构建requests验证verify的参数4- 锁定secode参数的作用 ok&#xff0c;让我们去获取verify接口中的响应&#xff01;&#xff01;&#xff01; 3…

java算法day12

java算法day12 199二叉树的右视图637二叉树的层平均值515 在每个树行中找最大值429 N叉树的层序遍历116 填充每个节点的下一个右侧节点指针 199 二叉树的右视图 这题还是层序遍历的板子&#xff0c;但是在处理上略有差异 这个题我一开始的想法就有误&#xff0c;因为我一开始…

基于PID控制器的双容控制系统matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1PID控制器的基本原理 4.2双容水箱系统的数学模型 5.完整工程文件 1.课题概述 基于PID控制器的双容控制系统matlab仿真&#xff0c;仿真输出PID控制下的水位和流量两个指标。 2.系统仿真结果 &…

Nginx七层(应用层)反向代理:SCGI代理scgi_pass篇

Nginx七层&#xff08;应用层&#xff09;反向代理 SCGI代理scgi_pass篇 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this art…

ENSP防火墙

实验拓扑图 需求&#xff1a; ENSP的配置&#xff1a; 防火墙&#xff1a; 交换机&#xff1a; 华为防火墙的配置&#xff1a; 接口配置&#xff1a; 安全区域&#xff1a; 安全策略&#xff1a; 办公区访问DMZ&#xff1a; 生产区访问DMZ&#xff1a; 游客区只能访问门户网…

[人工智能]对未来建筑行业的影响

作者主页: 知孤云出岫 目录 引言1. 人工智能在建筑行业的应用场景1.1 设计阶段1.2 施工阶段1.3 运营和管理 2. 关键技术2.1 机器学习2.2 计算机视觉2.3 自然语言处理2.4 大数据分析 3. 实际案例分析3.1 案例1&#xff1a;利用GAN生成建筑设计方案3.2 案例2&#xff1a;利用计算…

操作User表的CRUD增删改查(二):修改和删除

文章目录 修改运行发现数据库数据没有添加进去 修改 int u session.update(s, new User(1,"xiaoxiao",18));运行发现数据库数据没有添加进去 运行发现数据库没有添加进去数据&#xff0c;原因是默认是手动添加的&#xff0c;需要修改。 有两种方法然后再重新运行&a…

如何ssh远程Windows电脑

参考&#xff1a;https://www.jianshu.com/p/1321b46b40ee 上述教程中&#xff0c;直接根据微软的教程进行openssh安装 遇到的问题 远程windows电脑需要具备什么条件&#xff1f; 需要Windows电脑上安装了openssh server 远程Windows电脑的话&#xff0c;用户怎么创建&…

教育与社会的发展

生产力与教育的关系 政治经济制度与教育的关系 文化和人口与教育的关系