十三、list 类

devtools/2024/12/22 9:06:43/

Ⅰ . list 的介绍和使用

01 初识 list

我们已经学习过 string 和 vector 了,想必大家已经掌握了查文档的能力

现在我们去学习如何使用 list ,最好仍然打开文档去学习

list - C++ Reference

list 是一个顺序容器

允许在任意位置进行 O(1) 插入和删除的顺序容器,并提供双向迭代器

list 底层是双向链表

双向链表中每个元素存储在互不相关的独立结点中,在结点中通过两个指针指向其前后元素

list 与 forward_list 非常相似

最大的不同就是 forward_list 是单链表,只能向前迭代

④ 与其他序列式容器相比(array,vector,deque)

list 通常在任意位置进行插入、删除元素的效率更高,因为是 O(1)

list 和 forward_list 最大的缺陷是不支持随机位置的随机访问 举个例子:

如果要访问 list 中的第六个元素,必须从已知位置(如头部或尾部)迭代到该位置

在这段位置上迭代需要线性时间的时间开销,同时,list 还需要一些额外空间

以保存每个结点的相关联信息

02 创建 list

代码实现:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> l;return 0;
}

Ⅱ . list 的修改操作

01 修改操作的函数

02 push_back 

list 尾部插入值为 val 的元素

代码实现:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);return 0;
}

我们现在来打印一下

首先思考一个问题,还能使用下标 + 方括号的方式遍历嘛?

不行 因为 list 是链表,是通过指针连接的,所以不支持随机访问

而 string 和 vector 可以,因为它们的物理结构是连续的

迭代器遍历:

#include<iostream>
#include<list>
using namespace std;int main()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);// 迭代器list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}cout << endl;return 0;
}

运行结果如下:

范围 for 就更简单了:

	// 范围forfor (auto e : l)cout << e << " ";cout << endl;

如果我们想倒着遍历,我们可以使用反向迭代器

使用 rbegin() 和 rend()

反向迭代器:

	// 反向迭代器list<int>::reverse_iterator rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;

运行结果如下:

03 push_front

list 头部插入值为 val 的元素

代码实现:

void list_test2()
{list<int> l;l.push_front(1);l.push_front(2);l.push_front(3);l.push_front(4);for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

04 pop_back

删除 list 中的最后一个元素

void list_test3()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);cout << "删除前:";for (auto e : l)cout << e << " ";cout << endl;l.pop_back();cout << "删除后:";for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

如果表内没有元素,进行删除操作,会触发断言

05 pop_front

删除 list 中的第一个元素

void list_test4()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);cout << "删除前:";for (auto e : l)cout << e << " ";cout << endl;l.pop_front();cout << "删除后:";for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

06 insert

在上一节讲解 vector 实现的时候,我们对迭代器失效的问题进行了简单探讨

这里 list 的 insert 同样会涉及迭代器失效的问题,我们在模拟实现的时候再进行探讨

07 clear

清空 list 中的有效元素,使容器大小的 size 变为 0

代码演示:

void list_test5()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);cout << "清空前:";for (auto e : l)cout << e << " ";cout << endl;l.clear();cout << "清空后:";for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

08 erase

代码演示:

void list_test6()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);for (auto e : l)cout << e << " ";cout << endl;list<int>::iterator it = find(l.begin(), l.end(), 4);if (it != l.end()){l.erase(it);}else{cout << "没找到";}for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

Ⅲ . list 容量操作

01 size 返回有效结点个数

代码演示:

void list_test7() 
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);for (auto e : l) cout << e << " "; cout << endl;cout << "有效节点个数:";cout << l.size() << endl;
}

运行结果如下:

02 empty 检测容器是否为空

empty 是用来检测容器是否为空的,如果为空则返回 true,否则返回 false。

代码演示:

void list_test8()
{list<int> l;l.empty() == true ? cout << "为空" : cout << "不为空";
}

运行结果如下:

 

03 resize 调整容器大小

list 中的 resize 和之前的 resize 的 "扩容" 有点不一样,它没有容量。

这里的 resize 是调整容器的大小,使其包含 n​ 个元素。

代码演示:

void list_test9()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);for (auto e : l)cout << e << " ";cout << endl;l.resize(10, 5);for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

Ⅳ . list 的其他操作

01 reverse 逆置

代码演示:

void list_test10()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);for (auto e : l)cout << e << " ";cout << endl;l.reverse();for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

02 sort 排序

代码演示:

void list_test11()
{list<int> l;l.push_back(4);l.push_back(2);l.push_back(6);l.push_back(1);for (auto e : l)cout << e << " ";cout << endl;l.sort();for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

03 unique 去重

去重之前是有要求的,去重之前一定要先排序,如果不排序可能会去不干净

代码演示:

void list_test12()
{list<int> l;l.push_back(2);l.push_back(1);l.push_back(2);l.push_back(1);for (auto e : l)cout << e << " ";cout << endl;l.sort();cout << "去重后:";l.unique();for (auto e : l)cout << e << " ";cout << endl;
}

运行结果如下:

如果不排序,会导致去不干净:

void list_test12()
{list<int> l;l.push_back(2);l.push_back(1);l.push_back(2);l.push_back(1);for (auto e : l)cout << e << " ";cout << endl;//l.sort();cout << "去重后:";l.unique();for (auto e : l)cout << e << " ";cout << endl;
}

04 remove

remove 只需要给一个元素的值,它就可以自己找自己删

代码演示:

void list_test13() 
{list<int> l;l.push_back(10);l.push_back(20);l.push_back(30);l.push_back(40);for (auto e : l) cout << e << " "; cout << endl;// 如果删一个存在的元素l.remove(10);for (auto e : l) cout << e << " "; cout << endl;// 如果待删元素不存在l.remove(0);for (auto e : l) cout << e << " "; cout << endl;
}

运行结果如下:

 05 splice 接合

简单来说就是把一个链表转移到另一个链表中

代码演示:

void list_test14()
{list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);cout << "l1:";for (auto e : l1)cout << e << " ";cout << endl;list<int> l2;l2.push_back(10);l2.push_back(20);l2.push_back(30);cout << "l2:";for (auto e : l2)cout << e << " ";cout << endl;list<int>::iterator pos = l1.begin();// 把l2的内容接到l1的begin()前面l1.splice(pos, l2);cout << "接合后";for (auto e : l1)cout << e << " ";cout << endl;
}

运行结果如下:

 


http://www.ppmy.cn/devtools/96249.html

相关文章

【STM32嵌入式系统设计与开发拓展】——16_FreeRTOS操作系统

参考&#xff1a;链接: 正点原子 一、认识裸机和RTOS 裸机是无操作系统支持&#xff0c;程序直接运行在硬件上&#xff0c;开发者要自行处理硬件细节。早期单片机常采用&#xff0c;优点是性能和资源利用率高&#xff0c;缺点是开发难、可移植性差。RTOS 是实时操作系统&…

使用 onBeforeRouteUpdate 组合式函数提升应用的用户体验

title: 使用 onBeforeRouteUpdate 组合式函数提升应用的用户体验 date: 2024/8/15 updated: 2024/8/15 author: cmdragon excerpt: 摘要&#xff1a;本文介绍如何在Nuxt 3开发中使用onBeforeRouteUpdate组合式函数来提升应用用户体验。通过在组件中注册路由更新守卫&#xf…

高效记录与笔记整理的策略:工具选择、结构设计与复习方法

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

函数声明与函数表达式的区别是什么?

var init function() >函数表达式&#xff0c;函数在代码执行到当前行时才被执行&#xff0c;init才被赋值 function init()0 >函数声明&#xff0c;和var一样&#xff0c;会被提前到代码最前面定义 区别: 1) 以函数声明的方法定义的函数&#xff0c;函数名是必须的&am…

【数据结构详解】——归并排序(动图详解)

目录 &#x1f552; 1. 归并排序&#x1f558; 1.1 递归实现&#x1f558; 1.2 非递归实现 &#x1f552; 1. 归并排序 &#x1f4a1; 算法思想&#xff1a;归并排序是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法的一个非常典型的应用。将已有序的子…

100个练习学习Rust!可变性・循环・溢出

【0】准备 【1】构文・整数・变量 【2】 if・Panic・演练 ←前次 【3】可变性・循环・溢出 本次 这是“100 Exercise To Learn Rust”的第三次练习&#xff01;这次是关于两个循环结构的讨论&#xff0c;可能与上上次练习中讨论的溢出有关&#xff01; 本次相关的页面如下&…

Linux - 基础工具使用

文章目录 一、yum1、介绍2、功能3、语法4、使用 二、rzsz1、安装rzsz的指令2、介绍3、使用 三、vim基础使用1、介绍2、基础使用 四、gcc/g使用1、生成可执行文件过程2、语法3、常用选项4、编译过程5、动静态库6、包含头文件的多文件编译7、链接外部库 一、yum 1、介绍 Linux中…

laravel 11 使用jw-auth进行API 登录

首先安装 composer require tymon/jwt-auth 默认安装后我的版本是2.1 "require": {"php": "^8.2",...."tymon/jwt-auth": "^2.1"}, 发布包配置文件 php artisan vendor:publish --provider"Tymon\JWTAuth\Provider…