C++中STL六大组件List的简单介绍

一、前言

        C++非常重视效率,对效率有损失的代码常常是能省则省。使用list要包含的头文件是<list>,要包含头文件就是#iinclude <list>,List肯定是一种链表,我们不妨回忆一下那种链表插入删除效率最快也就是最简单,还能减少判断次数,链表的结尾是否要判断nullptr。毫无疑问,list所使用的结构是带头双向环形链表。带头意味着插入形式单一,无论链表中是否存在数据,都只需要将新结点的上一个指针和下一个指针做处理,省去判断是否存在结点,而且写起来也非常简单。双向意味着只要知道链结点的位置就可以访问它的下一个位置或是上一个位置,插入删除都十分方便,如果是单向还要一个一个的遍历查找。环形链表就更加简单了,学过双向链表、单(向)链表的同学都知道,不管是单链表还是双向链表尾插都十分不便,如果有固定的尾插地址维护起来更是难上加难,但是双向(可以往后也可以往前)环形链表根本就没有这样的顾虑,因为可以从开头往后走到达尾插位置。形状大概就像土家族的吊脚楼。

二、list的详细介绍

        在STL容器中,我们只要会其中的一个容器的接口,我们就可以触类旁通。不用抱太多疑虑。

        和大多数STL容器一样。包含的头文件还是它的本名<list>

        包含就要做#include <list>,不想加每次声明list对象和迭代器都加std::在对象之前的话#include <list>        using namespace std;也是可以的。

        2.1        size()函数和empty()函数

        注意该容器不是和Vector和String一样的数组存储。而是通过一个特质的结构体对象进行链接。(小编尽量快点出一个关于指针和结构体指针的专题。)连接的结点地址不一定要像数组一样连续,,所以list没有像Vector和String有容量capacity这个概念,地址分布可以尽量松散一些,可以不用申请那么大块空间,更好申请。size()函数就是反映list中的数据有多少。empty()反映list是否为空。

// 形如这样的结点进行链接。
// 这里是随便写的,list的结点肯定不长这样。比这要复杂。
struct List_Node
{// 要存储的内容。// 有模板的话,什么类型都可以。int _val;// 上一个结点的地址。struct List_Node* _prev;// 下一个结点的地址。struct List_Node* _next;
};#include <iostream>
#include <list>int main()
{std::list<int> lt;for (int i = 0; i <= 13; ++i){lt.push_back(i);lt.push_back(i);std::cout << "当i为   " << i << "     时list中的数据总量:      " << lt.size() << std::endl;}return 0;
}

        2.2        insert()函数和erase()函数

        通过Vector和String的学习,我们知道insert()函数和erase()函数都是在指定位置插入删除,同时用到的都是与指针有着相似作用的迭代器。下面话不多说,直接开始上示例。

#include <iostream>
#include <list>int main()
{std::list<int> lt;for (int i = 0; i <= 13; ++i){// 头插lt.insert(lt.begin(), i);// 尾插lt.insert(lt.end(), i);// std::cout << "当i为   " << i << "     时list中的数据总量:      " << lt.size() << std::endl;}//lt.unique();//lt.remove(10);// 范围for,C++创造者认为每次遍历都要写一个int太过于麻烦。// 所以直接支持了范围for。// 范围for会根据类中的begin()和end()函数(前面提到过的C++定好的函数名不要去改,不知道大家有没有印象。)// 提供的迭代器进行访问。for (auto& e : lt){std::cout << e << std::endl;}return 0;
}

        2.3        front()函数和back()函数

        前面小编提到链表头插和尾插,那我们怎么快速拿到链表首尾的数据,查看是否头插尾插成功了呢?front()和back()就可以很好的检测这一点。

#include <iostream>
#include <list>int main()
{std::list<int> lt;for (int i = 0; i <= 13; ++i){lt.insert(lt.begin(), i);lt.insert(lt.end(), i);std::cout << "第" << i << "行" << "front:         " << lt.front() << "        back:             " << lt.back() << std::endl;}return 0;
}

        2.4        begin()函数和end()函数

        关于begin()函数和end()函数有一些要补充的内容,Vector的迭代器是随机迭代器,与指针非常相似可以加减任意符合数组范围的值来访问该位置的值,而list的迭代器是双向迭代器只能通过++、--来改变访问的位置,毕竟list中的结点并不一定像Vector存储一样是连续的。

#include <iostream>
#include <list>int main()
{std::list<int> lt;for (int i = 0; i <= 13; ++i){lt.insert(lt.begin(), i);}std::list<int>::iterator it = lt.begin();while (it != lt.end()){std::cout << *it << std::endl;// 报错//it + 3;// 双向迭代器。++it;}return 0;
}

        2.5        push_front函数和push_back()函数

        通过函数名称可以得知这是头插和尾插函数。话不多说直接上案例。

#include <iostream>
#include <list>int main()
{std::list<int> lt;for (int i = 0; i <= 13; ++i){lt.push_front(i);lt.push_back(i);std::cout << "第" << i << "行" << "front:         " << lt.front() << "        back:             " << lt.back() << std::endl;}return 0;
}

        2.6        pop_front函数和pop_back()函数

        通过函数名称可以得知这是头删和尾删函数。和上面对比很好理解。那为什么Vector没有头插头删,list却有?因为效率!还是效率!Vector的结构就像数组一样,一个指针变量指向一块地址开头,进行访问使用。指针指向一块地址的开头该怎么头删?只能将要删除的位置之后的数据往前移动一个单位,正好将要删除位置的数据覆盖掉。这非常影响效率,所以没有实现该函数。不过大家可以试试deque容器,Vector和List的特性兼具,既可以头删又可以尾删。至于为什么等以后再说吧。

        2.7        unique()函数、remove()函数、remove_if()函数

        unique()函数是去重函数,remove()函数是删除数据为参数的函数,remove_if()函数就有一点超纲了,是根据条件删除,那怎么传条件呢?通过仿函数(就是像函数调用的类调用形式。)

#include <iostream>
#include <list>// 仿函数
class Like_Function
{
public:bool operator () (int x){// 删除偶数if (x % 2 == 0){// 函数返回值为true对应的参数会被删除。return true;}return false;}
};int main()
{std::list<int> lt;for (int i = 0; i <= 13; ++i){// 这里我故意插入两个相同值。// 头插lt.insert(lt.begin(), i);// 尾插lt.insert(lt.end(), i);}// 去重。lt.unique();// 去掉特殊值。lt.remove(10);// 可以传一个匿名对象(写起来方便,就相当于C语言的临时值)lt.remove_if(Like_Function(/*构造函数要的参数*/));for (auto& e : lt){std::cout << e << std::endl;}return 0;
}

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

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

相关文章

第十五节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - vue前端 生产部署

Vben Admin vben5 系列文章目录 💻 基础篇 ✅ 第一节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 ✅ 第二节:Vben Admin 最新 v5.0 (vben5) + Python Flask 快速入门 - Python Flask 后端开发详解(附源码) ✅ 第三节:Vben Admin 最新 v5.0 (vben5) + Python …

背包初步(0-1背包、完全背包)

当月光洒在我的脸上 我想我就快变了模样 有一种叫做撕心裂肺的汤 喝了它有神奇的力量 动态规划初步&#xff08;完全背包&#xff09; 目录动态规划初步&#xff08;完全背包&#xff09;0-1背包简介完全背包检查数组是否存在有效划分&#xff08;前缀划分DP&#xff09;单词拆…

Linux驱动06 --- UDP

目录 一、UDP 1.1 介绍 1.2 UDP 的通信方式 1.3 单播 发送函数 接收函数 1.4 广播 1.5 组播/多播 一、UDP 1.1 介绍 传输层的另外一个协议 面向无连接&#xff0c;不稳定&#xff0c;速度快&#xff0c;可以一对多 UDP&#xff08;User Datagram Protocol&…

AJAX 投票:技术解析与应用场景

AJAX 投票:技术解析与应用场景 引言 随着互联网技术的不断发展,Web应用的用户体验越来越受到重视。AJAX(Asynchronous JavaScript and XML)作为一种重要的技术,在实现异步数据交互方面发挥着关键作用。本文将深入探讨AJAX投票系统的技术原理、应用场景以及优化策略。 A…

【字节跳动】数据挖掘面试题0017:推荐算法:双塔模型,怎么把内容精准地推送给用户

文章大纲 双塔模型:推荐算法中的“高效匹配引擎一、双塔模型的核心思想:“分而治之” 的匹配逻辑二、双塔模型的结构:从特征输入到相似度输出1. 输入层:特征的 “原材料处理”2. 塔网络层:用户与物品的“个性化编码”3. 交互层:向量相似度的“偏好打分”三、双塔模型的优…

7月14日日记

数学类今天考完最后一科英语放假回家了。有点羡慕他们。今天英语成绩出来了&#xff0c;我是89分&#xff0c;一开始有点失望&#xff0c;感觉没有上90&#xff0c;这是一个很好的冲击4.0 的机会。但是后来一想好像也没什么可惜的&#xff0c;这个分数还是很高的。舍友小林是90…

js的局部变量和全局变量

全局变量常常定义在函数外&#xff0c;具有全局定义域&#xff0c;在整个js代码的任何地方都可以使用&#xff0c;这个就叫全局变量局部变量定义在函数内部&#xff0c;只在当前函数的定义域可以被使用&#xff0c;而且不同的函数可以定义相同的局部变量&#xff0c;他们之间相…

C++ 多态详解:从概念到实现原理----《Hello C++ Wrold!》(14)--(C/C++)

文章目录前言多态的概念多态的定义和实现虚函数虚函数的重写(覆盖)多态的构成条件override 和 final&#xff08;C11提出&#xff09;finaloverride重载、覆盖(重写)、隐藏(重定义)的对比抽象类接口继承和实现继承多态的原理虚函数表(也叫做虚表)引申:虚表的打印多态的原理静态…

Node.js + Express的数据库AB View切换方案设计

方案总览数据导入过程&#xff1a; - 根据控制表判断当前活跃组&#xff08;假设当前活跃的是a&#xff0c;那么接下来要导入到b&#xff09;。 - 清空非活跃表&#xff08;即b表&#xff09;的数据&#xff0c;然后将新数据导入到b表。 - 切换控制表&#xff0c;将活…

C++_编程提升_temaplate模板_案例

类模板案例案例描述: 实现一个通用的数组类&#xff0c;要求如下&#xff1a;可以对内置数据类型以及自定义数据类型的数据进行存储将数组中的数据存储到堆区构造函数中可以传入数组的容量提供对应的拷贝构造函数以及operator防止浅拷贝问题提供尾插法和尾删法对数组中的数据进…

Win11系统安装Anaconda环境极简教程

Win11系统安装Anaconda环境极简教程 &#x1f4e5; 第一步&#xff1a;下载 Anaconda 安装包 打开浏览器&#xff0c;访问 Anaconda 官网&#xff0c;选择View All Installers 选择所需版本&#xff08;此文以2024.02-1为例&#xff09;&#xff0c;点击进行下载&#xff08;…

Datawhale AI夏令营-基于带货视频评论的用户洞察挑战赛

一.赛事目标基于星火大模型Spark 4.0 Ultra&#xff0c;对视频和评论的数据进行商品识别&#xff0c;情感分析&#xff0c;归类分析&#xff0c;最终为带货效果进行评价。并通过优化模型来提高评价准确度二.赛事环境1.基础平台&#xff1a;星火大模型Spark 4.0 Ultra2.赛事数据…

如何基于FFMPEG 实现视频推拉流

文章目录 前言环境准备为什么选择 FFmpeg什么是nginx 1.7.11.3 GryphonNginx的conf配置启动nginx推流命令接收视频流Untiy播放视频流最后前言 我们经常会有在电脑上实现推拉流的需求,Unity 和Unreal 都提供了基于WebRTC 的视频流方案,效果还不错,但是当我们需要推拉整个电脑…

飞算JavaAI:从情绪价值到代码革命,智能合并项目与定制化开发新范式

目录一、飞算 JavaAI 是什么&#xff1f;二、飞算JavaAI&#xff1a;安装登录2.1 IDEA插件市场安装&#xff08;推荐&#xff09;2.2 离线安装包三、飞算JavaAI核心功能&#xff1a;一键生成完整工程代码功能背景3.1 理解需求3.2 设计接口3.3 表结构自动设计3.4 处理逻辑&#…

Python 基础语法与数据类型(十一) - 类 (class) 与对象 (实例)

文章目录1. 什么是类 (Class)&#xff1f;1.1 定义一个类2. 什么是对象 (Object) 或实例 (Instance)&#xff1f;2.1 创建对象&#xff08;实例化&#xff09;3. 访问属性和调用方法4. 类属性 vs 实例属性5. self 的重要性总结练习题练习题答案前几篇文章我们学习了变量、数据类…

精准数据检索+数据飞轮自驱优化,彩讯AI知识库助力企业知识赋能和效率创新

近两年&#xff0c;人工智能技术的精细化发展&#xff0c;让知识库概念重新成为“热门词汇”&#xff0c;腾讯ima等智能工作台产品为个人用户打造专属知识库&#xff0c;而面向B端市场&#xff0c;企业AI知识库也逐步成为企业集中存储与管理核心文档、数据、经验和流程的知识中…

打破空间边界!Nas-Cab用模块化设计重构个人存储逻辑

文章目录前言1. Windows安装Nas-Cab2. 本地局域网连接Nas-Cab3. 安装Cpolar内网穿透4. 固定Nas-Cab 公网地址"数据管理不该受制于硬件形态或地理边界。这个开源方案证明&#xff1a;当功能模块化且可扩展时&#xff0c;私有云可以像水一样渗透进所有设备——现在就去Git仓…

Sigma-Aldrich细胞培养基础知识:细胞培养的安全注意事项

细胞培养实验室风险评估风险评估的主要目的是防止人员受伤&#xff0c;保护财产&#xff0c;并避免对个人和环境的伤害。在许多国家&#xff0c;法律要求进行风险评估。例如&#xff0c;英国的《英国职业健康与安全法案&#xff08;1974年&#xff09;》就是一个例子。欧洲共同…

Imx6ull用网线与电脑连接

理解工作方式没有路由器时&#xff0c;可以使用&#xff0c;只要保持虚拟机的两个网卡一个与电脑在同一网,一个与板子在同一网段(保持通信)就可以从虚拟机往板子下载第一步&#xff1a;查看电脑连接的网络这一步是在找到主机ip地址这两步在其他同类教程里一样的第二步:设置以太…

力扣454.四数相加Ⅱ

给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a;0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0示例 1&#xff1a;输入&#xff1a;nums1 [1,2], nums2 …