C++ list介绍
文章目录
- 1. list简介
- 2. list的实现框架
- 2.1 链表结点
- 2.2 链表迭代器
- 2.3 链表
- 3. list迭代器及反向迭代器设计
- 3.1 list迭代器
- 3.2 list反向迭代器
- 3.3 list迭代器失效
- 4. list与vector比较
1. list简介
list,即链表。
链表的种类有很多,是否带头结点,是否循环,是否双向——list是带头双向循环链表。
关于list的使用本文中不作介绍,本文将重点放在list的实现框架、list的迭代器和反向迭代器设计、list的迭代器失效上。
2. list的实现框架
list的实现,实质上实现了三个类。
对于链表而言,只需要一个指向头结点的指针,即可拿到整个链表。这句话中就包括了要实现的三个类:链表、链表的迭代器和链表的结点。
2.1 链表结点
首先,我们需要将链表的结点封装成一个类。C++中很少使用内部类,一般定义成struct(即class + public), 允许外部使用即可。
结点类是最基础的一个类,指向它实例化出对象的指针,既是链表迭代器类的成员变量,也是链表类的成员变量。
2.2 链表迭代器
在vector当中,迭代器是用原生指针即可实现,这是因为vector的底层实际上是一个具有连续存储空间的动态数组,迭代器的行为与原生指针的行为相同。
但对于链表,链表结点的存储空间不一定是连续的,因此原生指针的行为不一定能达到目的。而将链表的迭代器封装为一个类,即可通过运算符重载,实现想要的行为。
2.3 链表
链表类,是我们最终的主体。它仍然以指向结点的指针作为成员变量,但是这个成员变量是特殊的,其为指向链表头结点(即哨兵位)的指针。
3. list迭代器及反向迭代器设计
3.1 list迭代器
要设计list的迭代器,就会想到还要设计list的const迭代器。
需要说明的是,const迭代器并不是简单地在普通迭代器前加上const。
const iterator it;
//这里const实际修饰it,使得it本身不能改变
//const迭代器并不是迭代器本身不能改变,而是迭代器指向地对象不能被修改
因此,通过以上分析可得,如果要将迭代器封装成类,普通迭代器与const迭代器,实为两个不同的类。
但如果两种迭代器都分别实现的话,会发现代码只有很细微的差别,此时我们会想到将迭代器设计为类模板,普通迭代器与const迭代器都是这个模板的实例化。
那么,如何设计这个类模板呢?
考虑到,普通迭代器与const迭代器,只有在解引用运算符重载与成员访问运算符(即->)重载时有返回值上的区别(普通指针与const指针、普通引用与const引用),所以需要三个模板参数——确定节点数据类型的类型参数T,确定指针类型的参数Ptr和确定引用类型的参数Ref。


有几点需要说明:
- list的迭代器是bidirectional iterator,即双向迭代器。双向迭代器只重载++和- -,不重载加减一个具体数字。双向迭代器,关系运算符也只重载 == 和 ! = 。
- 关于解引用操作符与成员访问操作符的重载说明如下。
链表的结点是一个类,对迭代器解引用是为了拿到其中的数据
当迭代器是用 -> 这个操作符时,说明结点中所存储的数据应是一个自定义类型,通过->操作符去访问这个自定义类型允许外部访问的成员函数或成员变量
//使用代码示例如下所示
int main()
{list<string> l1;l1.push_back("abc");l1.push_back("efg");list<string>::iterator it = l1.begin();while(it != l1.end()){//以下两条语句打印出的结果相同cout << (*it).size() << endl;cout << it->size() << endl;//it->size()实则为it->->size(),有两个箭头,因为->运算符重载中返回的是&_node->_data,只不过通常只写一个箭头it++;}return 0;
}
3.2 list反向迭代器
反向迭代器是一种适配器,或者说是运用了适配器的设计模式实现的,本质上就是对普通迭代器的复用。具体实现时,将普通迭代器设置为反向迭代器的成员变量,实现反向迭代器的成员函数时,复用普通迭代器的成员函数即可。
3.3 list迭代器失效
相比于vector的迭代器失效,list迭代器失效的情况就要少得多。本质上,这是因为链表结构各节点间的插入删除并不会互相影响,不会出现vector中需要前移或后移的情况,而且链表也不需要像vector那样异地扩容。
所以,insert不会导致list迭代器失效,erase只会导致指向被删除结点的迭代器失效。
4. list与vector比较
在属性上,list与vector的差别,可以近似为链表与顺序表的差别,而且list的迭代器为双向迭代器,vector的迭代器是随机迭代器。
这个迭代器上的区别,使得vector对象可以使用算法库中的sort(这个函数要求传随机迭代器),而list无法使用,因此list自身实现了一个sort作为成员函数,但是这个list的排序速度是很慢的,甚至慢于将list的数据拷贝到vector中,在vector中排序完后再拷贝会list的速度,因此慎用list的排序。
在功能上,如果想要在任意位置插入和删除数据,推荐使用list;如果想要在任意位置快速存取数据,推荐使用vector。
相关文章:
C++ list介绍
文章目录 1. list简介2. list的实现框架2.1 链表结点2.2 链表迭代器2.3 链表 3. list迭代器及反向迭代器设计3.1 list迭代器3.2 list反向迭代器3.3 list迭代器失效 4. list与vector比较 1. list简介 list,即链表。 链表的种类有很多,是否带头结点&#…...
Java - 在Linux系统上使用OpenCV和Tesseract
系统环境 确保Linux系统安装了cmake构建工具,以及java和ant(这两者如果没有,可能会影响到后面编译opencv生成.so和.jar文件)。 sudo apt-get update sudo apt-get install build-essential sudo apt install cmake build-essen…...
自有服务与软件包
—— 小 峰 编 程 目录 编辑 一、自有服务概述 二、systemctl管理服务命令 1、显示服务 2、查看启动和停止服务 3、服务持久化 三、常用自有服务(ntp,firewalld,crond) 1、ntp时间同步服务 1)NTP同步服务器原理 2)到哪里去找NPT服务…...
Python 鼠标轨迹 - 防止游戏检测
一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…...
BootstrapBlazor Table组件 使用的注入 数据服务 实现类:使用 EF Core
一、使用示例:UsersManager.razor 注:TLog 相关内容参见 .NET 9.0 的 Blazor Web App 项目、Bootstrap Blazor 组件库、自定义日志 TLog 使用备忘-CSDN博客 page "/Log/TLogManager"<Table TItem"TLogEntity" DataService&qu…...
chrome-mojo C++ Bindings API
概述 Mojo C 绑定 API 利用C 系统 API提供一组更自然的原语,用于通过 Mojo 消息管道进行通信。结合从Mojom IDL 和绑定生成器生成的代码,用户可以轻松地跨任意进程内和进程间边界连接接口客户端和实现。 本文档通过示例代码片段提供了绑定 API 用法的详…...
git如何把多个commit合成一个
在 Git 中,如果你想把多个提交(commit)合并成一个,可以使用 git rebase 或 git reset 来完成。下面是两种常用方法: 方法一:使用 git rebase(推荐) git rebase 是合并多个提交为一…...
java: framework from BLL、DAL、IDAL、MODEL、Factory using oracle
oracel 21c sql: -- 创建 School 表 CREATE TABLE School (SchoolId CHAR(5) NOT NULL,SchoolName NVARCHAR2(500) NOT NULL,SchoolTelNo VARCHAR2(8) NULL,PRIMARY KEY (SchoolId) );CREATE OR REPLACE PROCEDURE addschool(p_school_id IN CHAR,p_school_name IN NVARCHAR2,p…...
RPA与深度学习结合
什么是RPA RPA即机器人流程自动化(Robotic Process Automation),它是一种利用软件机器人模拟人类在计算机上的操作,按照预设的规则自动执行一系列重复性、规律性任务的技术。这些任务可以包括数据录入、文件处理、报表生成、系统…...
Ubuntu22.04部署deepseek大模型
Ollama 官方版 Ollama 官方版: https://ollama.com/ 若你的显卡是在Linux上面 可以使用如下命令安装 curl -fsSL https://ollama.com/install.sh | shollama命令查看 rootheyu-virtual-machine:~# ollama -h Large language model runnerUsage:ollama [flags]ollama [comman…...
如何设置Jsoup请求头模拟浏览器访问?
在使用 Jsoup 进行网络爬虫开发时,设置请求头以模拟浏览器访问是非常重要的。这不仅可以帮助我们更好地伪装爬虫,避免被目标网站识别,还可以确保请求的合法性。以下是如何设置 Jsoup 请求头以模拟浏览器访问的详细步骤和示例代码。 1. 设置请…...
JVM 类加载子系统在干什么?
JVM 类加载子系统是什么? 类加载子系统(Class Loader Subsystem)是 JVM 负责 加载、链接和初始化 .class 文件的组件。它的主要作用是将字节码文件加载进 JVM 并准备执行。 类加载器(ClassLoader)是 字节码的搬运工&…...
Redis数据库(二):Redis 常用的五种数据结构
Redis 能够做到高性能的原因主要有两个,一是它本身是内存型数据库,二是采用了多种适用于不同场景的底层数据结构。 Redis 常用的数据结构支持字符串、列表、哈希表、集合和有序集合。实现这些数据结构的底层数据结构有 6 种,分别是简单动态字…...
《量化绿皮书》Chapter 3 Calculus and Linear Algebra 微积分与线性代数(二)
《A Practical Guide To Quantitative Finance Interviews》,被称为量化绿皮书,是经典的量化求职刷题书籍之一,包含以下七章: Chapter 1 General Principles 通用技巧 Chapter 2 Brain Teasers 脑筋急转弯 Chapter 3 Calculus and…...
网络安全溯源 思路 网络安全原理
网络安全背景 网络就是实现不同主机之间的通讯。网络出现之初利用TCP/IP协议簇的相关协议概念,已经满足了互连两台主机之间可以进行通讯的目的,虽然看似简简单单几句话,就描述了网络概念与网络出现的目的,但是为了真正实现两台主机…...
BS架构(笔记整理)
楔子.基本概念 1.在网络架构中: 服务器通常是集中式计算资源,负责处理和存储数据;客户机是请求这些服务的终端设备,可能是个人电脑或移动设备;浏览器则是客户机上用来与服务器交互的工具,负责展示网页内容…...
06排序 + 查找(D2_查找(D2_刷题练习))
目录 1. 二分查找-I 1.1 题目描述 1.2 解题思路 方法:二分法(推荐使用) 2. 二维数组中的查找 2.1 题目描述 2.2 解题思路 方法一:二分查找(推荐使用) 3. 寻找峰值 3.1 题目描述 3.2 解题思路 方…...
客户端渲染和服务端渲染
二者本质的区别:是在哪完成了 HTML 的拼接,服务端渲染是在服务端拼接,客户端渲染是在客户端拼接。 服务端渲染的优缺点 优点 SEO 友好,服务端渲染更有利于爬虫爬取信息。 更快的首屏渲染,因为 HTML 已经在服务端生…...
C++ 设计模式 - 访问者模式
一:概述 访问者模式将作用于对象层次结构的操作封装为一个对象,并使其能够在不修改对象层次结构的情况下定义新的操作。 《设计模式:可复用面向对象软件的基础》一书中的访问者模式因两个原因而具有传奇色彩:一是因为它的复杂性&a…...
海云安开发者智能助手(D10)全面接入DeepSeek,赋能开发者安全高效编码新范式
海云安正式宣布完成与DeepSeek(深度求索)的深度技术融合,旗下核心产品D10开发者智能助手全面接入DeepSeek R1模型。此次合作标志着海云安在"AI驱动开发安全"领域实现重要突破。数据显示,通过DeepSeek R1模型的优化与蒸馏…...
服务器绑定 127.0.0.1 和 0.0.0.0 的区别
前言 IP 地址实际上并不是分配给计算机的,而是分配给网卡的,因此当计算机上存在多块网卡时,每一块网卡都会有自己的 IP 地址。 绑定 127.0.0.1 是绑定到 lookback 这个虚拟的本地回环接口,该接口只处理本机上的数据,…...
ML.NET库学习005:基于机器学习的客户细分实现与解析
文章目录 ML.NET库学习005:基于机器学习的客户细分实现与解析项目主要目的和原理目的原理 项目概述实现的主要功能主要流程步骤使用的主要函数方法关键技术 主要功能和步骤功能详细解读详细步骤解析 数据集及其处理步骤数据集处理步骤关键处理步骤原理1. 数据清洗与…...
分布式id探索
一、为什么要使用分布式id? 随着数据量增加,数据需要进行水平拆分,但表自增id无法满足唯一性; 二、分布式id的特点 1唯一性 2 趋势递增、单调递增(数据库中存放的数据结构数据从小到大有序排列)࿰…...
互联网协议套件中的服务类型(RFC 1349)技术解析与总结
1. 背景与核心目标 RFC 1349 是对 IP 协议头部 服务类型(Type of Service, TOS)字段语义的更新与澄清文档,发布于 1992 年。其主要目标包括: 重新定义 TOS 字段的用途:明确 TOS 字段的语义,解决历史标准中的…...
java-初识List
List: List 是一个接口,属于 java.util 包,用于表示有序的元素集合。List 允许存储重复元素,并且可以通过索引访问元素。它是 Java 集合框架(Java Collections Framework)的一部分 特点: 有序…...
【Linux系统】—— 简易进度条的实现
【Linux系统】—— 简易进度条的实现 1 回车和换行2 缓冲区3 进度条的准备代码4 第一版进度条5 第二版进度条 1 回车和换行 先问大家一个问题:回车换行是什么,或者说回车和换行是同一个概念吗? 可能大家对回车换行有一定的误解࿰…...
一文学会:用DeepSeek R1/V3 + AnythingLLM + Ollama 打造本地化部署的个人/企业知识库,无须担心数据上传云端的泄露问题
文章目录 前言一、AnythingLLM 简介&基础应用1.主要特性2.下载与安装3.配置 LLM 提供商4.AnythingLLM 工作区&对话 二、AnythingLLM 进阶应用:知识增强使用三、AnythingLLM 的 API 访问四、小结1.聊天模式2.本地存储&向量数据库 前言 如果你不知道Olla…...
开源身份和访问管理方案之keycloak(一)快速入门
文章目录 什么是IAM什么是keycloakKeycloak 的功能 核心概念client管理 OpenID Connect 客户端 Client Scoperealm roleAssigning role mappings分配角色映射Using default roles使用默认角色Role scope mappings角色范围映射 UsersGroupssessionsEventsKeycloak Policy创建策略…...
C++STL(六)——list模拟
目录 本次所需实现的三个类一、结点类的模拟实现构造函数 二、迭代器类的模拟实现为什么有迭代器类迭代器类的模板参数说明构造函数运算符的重载- -运算符的重载和!运算符的重载*运算符的重载->运算符的重载引入模板第二个和第三个参数 三、list的模拟实现3.1 默认成员函数构…...
HTML5--网页前端编程(下)
HTML5–网页前端编程(下) 9.常用标签下 (1)表格标签 用来展示数据,显示数据,规整条理,可读性好 基本语法 <table><tr> <td>单元格内的文字</td> <td>单元格内的文字</td>… </tr> <tr> <td>单元格内的文字&l…...
