当前位置: 首页 > news >正文

C++ 学习系列 -- std::list

一  std::list 介绍

       list 是 c++ 中的序列式容器,其实现是双向链表,每个元素都有两个指针,分别指向前一个节点与后一个节点

      链表与数组都是计算机常用的内存数据结构,与数组连续内存空间不一样的地方在于,链表的空间是不连续的,链表是将一块块不连续的内存串联起来使用。

    正是由于链表的内存不连续这一特点,所以不能像数组一样,可以根据位置随机的访问每个元素,而链表我们压根不知道每个元素的实际位置到底在哪块内存区域。

     查找某个元素需要遍历整个链表,直到找到目标元素位置,时间复杂度是 O(n);

    在链表中插入一个元素与删除一个元素的时间复杂度是 O(1);

二   c++ 中 stl 链表结构

1. list 结构

   list  结构 (借用侯捷老师的一张图片来):

  

  由上面的结构上可以看出,list 是一个循环链表,链表的尾端是一个空节点,不存储任何数据。

三   c++ 中 stl 链表使用

 1  构造函数

构造函数说明
list()空构造函数
list( size_type count, const T& value)初始化一个元素数量为 count 个的 value 元素
list( std::initializer_list<T> init)利用列表初始化 list
list( InputIt first, InputIt last)利用迭代器的起始于终止位置初始化 list

 2   容器修改

函数说明
clear() 清空所有元素
insert在指定位置插入元素
emplace在指定位置插入元素, 可以通过直接传入元素类的构造参数实现原地构造
erase移除指定元素
push_backappend 元素到链表的尾部
pop_back将链表尾部元素弹出
push_frontappend 元素到链表的头部
pop_front将链表头部元素弹出
emplace_backappend 元素到链表的尾部, 可以通过直接传入元素类的构造参数实现原地构造
emplace_frontappend 元素到链表的头部, 可以通过直接传入元素类的构造参数实现原地构造

 3  容器访问

函数说明
begin返回头部元素的迭代器
end返回尾部元素的迭代器
rbegin返回尾部元素的迭代器
rend返回头部元素的迭代器
front返回头部元素的引用
back返回尾部元素的引用

4  容器容量

函数说明
empty判断 list是否为空
size返回 list 存储元素的个数
#include<iostream>
#include<list>int main()
{// 1. 构造函数std::list<int> list;auto iter = list.begin();std::cout << *iter << "--- " << std::endl;;// 2. 容器修改list.push_back(1);list.push_back(2);list.push_back(3);list.push_back(4);list.push_back(5);list.push_front(11);list.push_front(22);list.pop_back();list.pop_front();list.insert(list.begin(), 666);// 3. 容器访问for(auto iter = list.begin(); iter != list.end();iter++){std::cout << *iter << " "; // 666 11 1 2 3 4}std::cout << "" << std::endl;for(auto iter = list.rbegin(); iter != list.rend();iter++){std::cout << *iter << " "; // 4 3 2 1 11 666}std::cout << "" << std::endl;std::cout << "first: " << list.front() << ", finish: " << list.back() << std::endl; // first: 666, finish: 4// 4. 容器容量std::cout << "empyt: " << list.empty() << std::endl; // 0std::cout << "size: "<< list.size() << std::endl; // 6list.clear();std::cout << "empyt: " << list.empty() << std::endl; // 1std::cout << "size: "<< list.size() << std::endl; // 0return 0;
}

四  简单实现

  

// my_list.h#include<memory>
#include<iostream>template<typename T>
struct _List_Node
{typedef _List_Node node;_List_Node(){prev = nullptr;next = nullptr;}_List_Node(T& da):data(da){prev = nullptr;next = nullptr;}_List_Node(T&& da):data(da){prev = nullptr;next = nullptr;}~_List_Node(){prev = nullptr;next = nullptr;}node* prev;node* next;T data;
};template<typename T>
struct _List_Iterator
{typedef T valueType;typedef T& refrence;typedef T* pointer;typedef  _List_Node<T> node;_List_Iterator(node* val):data(val){}_List_Iterator& operator++(){this->data = this->data->next;return *this;}_List_Iterator operator++(int){_List_Iterator tmp = *this;++(*this);return tmp;}_List_Iterator& operator--(){this->data = this->data->prev;return *this;}_List_Iterator operator--(int){_List_Iterator tmp = *this;--(*this);return tmp;}T& operator*(){return this->data->data;}bool operator != (_List_Iterator& other){return this->data != other->data;}bool operator == (_List_Iterator& other){return this->data == other.data;}bool operator != (_List_Iterator&& other){return this->data != other.data;}bool operator == (_List_Iterator&& other){return this->data == other.data;}node*  data;
};template<typename T>
class my_list
{typedef  _List_Node<T>  node;typedef  _List_Iterator<T> iterator;
public:my_list():count(0){next_curr = new node;pre_curr = next_curr;finish = new node;next_curr->next = finish;finish->next = next_curr;pre_curr->prev = finish;finish->prev = pre_curr;}~my_list(){node* tmp = pre_curr;while (tmp != nullptr) {node* tt = tmp->next;delete tmp;tmp = tt;}}void push_back(T& val){std::cout << "count: " << count << std::endl;if(count == 0)next_curr->data = val;else {node* tmp = new node(val);tmp->next = next_curr->next;tmp->next->prev = tmp;next_curr->next = tmp;tmp->prev = next_curr;next_curr = next_curr->next;}count++;}void push_back(T&& val){push_back(val);}void push_front(T& val){if(count == 0)pre_curr->data = val;else {node* tmp = new node(val);tmp->prev = pre_curr->prev;pre_curr->prev->next = tmp;tmp->next = pre_curr;pre_curr->prev = tmp;pre_curr = pre_curr->prev;}count++;}void push_front(T&& val){push_front(val);}void pop_back(){if(count == 0){return;} else{node* tmp = next_curr;next_curr->prev->next = next_curr->next;next_curr->next->prev = next_curr->prev;next_curr = next_curr->prev;delete tmp;count--;}}void pop_front(){if(count == 0){return;} else{node* tmp = pre_curr;finish->next = pre_curr->next;pre_curr->next->prev = finish;pre_curr = pre_curr->next;delete tmp;count--;}}int size(){return count;}iterator begin(){return iterator(pre_curr);}iterator end(){return iterator(finish);}iterator rbegin(){return iterator(finish->prev);}iterator rend(){return iterator(pre_curr->prev);}void insert(iterator pos, T& val){node* tmp = new node(val);pos.data->prev->next = tmp;tmp->prev = pos.data->prev;tmp->next = pos.data;pos.data->prev = tmp;if(pos.data == pre_curr){pre_curr = pre_curr->prev;}else if(pos.data == next_curr){next_curr = next_curr->next;}count++;}void insert(iterator pos, T&& val){insert(pos, val);}template<typename ... Args>void emplace(iterator pos, Args... args){node* tmp = new node(std::forward<Args>(args)...);pos.data->prev->next = tmp;tmp->prev = pos.data->prev->next;tmp->next = pos.data;pos.data->prev = tmp;count++;}void erase(iterator pos){node* tmp = pos.data;tmp->prev = tmp->next;delete tmp;count--;}void clear(){while (pre_curr->next != finish) {pop_back();}count = 0;}T& front(){return pre_curr->data;}T& back(){return next_curr->data;}bool empty(){return count == 0;}public:node* next_curr = nullptr;node* pre_curr = nullptr;node* finish = nullptr;int count;
};// main.cpp
#include<iostream>
#include<my_list.h>int main()
{// 1. 构造函数my_list<int> list;// 2. 容器修改list.push_back(1);list.push_back(2);list.push_back(3);list.push_back(4);list.push_back(5);list.push_front(11);list.push_front(22);// 22 11 1 2 3 4 5list.pop_back();list.pop_front();list.insert(list.begin(), 666);// 3. 容器访问for(auto iter = list.begin(); iter != list.end();iter++){std::cout << *iter << " "; // 666 11 1 2 3 4}std::cout << "" << std::endl;for(auto iter = list.rbegin(); iter != list.rend();iter--){std::cout << *iter << " "; // 4 3 2 1 11 666}std::cout << "" << std::endl;std::cout << "first: " << list.front() << ", finish: " << list.back() << std::endl; // first: 666, finish: 4// 3. 容器容量std::cout << "empty: " << list.empty() << std::endl; // 0std::cout << "size: "<< list.size() << std::endl; // 6list.clear();std::cout << "empyt: " << list.empty() << std::endl; // 1std::cout << "size: "<< list.size() << std::endl; // 0return 0;
}

相关文章:

C++ 学习系列 -- std::list

一 std::list 介绍 list 是 c 中的序列式容器&#xff0c;其实现是双向链表&#xff0c;每个元素都有两个指针&#xff0c;分别指向前一个节点与后一个节点 链表与数组都是计算机常用的内存数据结构&#xff0c;与数组连续内存空间不一样的地方在于&#xff0c;链表的空间是不…...

YOLOv8血细胞检测(6):多维协作注意模块MCA | 原创独家创新首发

💡💡💡本文改进:多维协作注意模块MCA,效果秒杀ECA、SRM、CBAM,创新性十足,可直接作为创新点使用。 MCA | 亲测在血细胞检测项目中涨点,map@0.5 从原始0.895提升至0.910 收录专栏: 💡💡💡YOLO医学影像检测:http://t.csdnimg.cn/N4zBP ✨✨✨实战医学影…...

FFmpeg横竖版视频互换背景模糊一键生成

视频处理是现代多媒体应用中常见的需求。其中横竖版视频互换和背景模糊是视频编辑中常见的操作。FFmpeg是一个功能强大的工具,适用于这些任务。 本文将详细介绍如何使用FFmpeg进行横竖版视频互换和背景模糊。 文章目录 操作命令与命令说明横版转竖版竖版转横版背景模糊处理横…...

Java 华为真题-小朋友分班

需求&#xff1a; 题目描述 幼儿园两个班的小朋友在排队时混在了一起&#xff0c;每位小朋友都知道自己是否与前面一位小朋友同班&#xff0c;请你帮忙把同班的小朋友找出来小朋友的编号是整数&#xff0c;与前一位小朋友同班用Y表示&#xff0c;不同班用N表示学生序号范围(0&…...

机器学习必修课 - 编码分类变量 encoding categorical variables

1. 数据预处理和数据集分割 import pandas as pd from sklearn.model_selection import train_test_split导入所需的Python库 !git clone https://github.com/JeffereyWu/Housing-prices-data.git下载数据集 # Read the data X pd.read_csv(/content/Housing-prices-data/t…...

ClickHouse进阶(二十二):clickhouse管理与运维-服务监控

进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Kerberos安全认证-CSDN博客 📌订阅:拥抱独家专题,你的订阅将点燃我的创作热情! 👍点赞:赞同优秀创作,你的点赞是对我创…...

Hadoop使用hdfs指令查看hdfs目录的根目录显示被拒

背景 分布式部署hadoop,服务机只有namenode节点,主机包含其他所有节点 主机关机后,没有停止所有节点,导致服务机namenode继续保存 再次开启主机hadoop,使用hdfs查看hdfs根目录的时候显示访问被拒 解决方案 1.主机再次开启hadoop并继续执行关闭 2.服务器再次开启hadoop并继…...

[Mac] 安装paddle-pipelines出现 ERROR: Failed building wheel for lmdb

今天在mac换了新系统&#xff0c;然后重新安装paddle-piplines的时候出现了下面的问题&#xff1a; xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrunerror: comma…...

LED灯亮灭

.text .global _start _start: 设置GPIO寄存器的时钟使能  RCC_MP_AHB4ENSETR[4]->1 0x50000a28LDR R0,0x50000A28LDR R1,[R0] 从R0为起始地址的&#xff14;个字节数据取出放入R1中ORR R1,R1,#(0x1<<4) 第四位设置为1STR R1,[R0] 写回LDR R0,0x5000…...

Acwing.143 最大异或对(trie树)

题目 在给定的N个整数A1&#xff0c;A2 . …Ax中选出两个进行xor(异或)运算&#xff0c;得到的结果最大是多少? 输入格式 第一行输入一个整数N。 第二行输入N个整数A1~AN。 输出格式 输出一个整数表示答案。 数据范围 1 ≤N ≤105,0≤A<231 输入样例: 3 1 2 3输出样…...

day10.8ubentu流水灯

流水灯 .text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28LDR R0,0X50000A28LDR R1,[R0] 从r0为起始地址的4字节数据取出放在R1ORR R1,R1,#(0x1<<4) 第4位设置为1STR R1,[R0] 写回2.设置PE10管脚为输出模式 G…...

transformer系列5---transformer显存占用分析

Transformer显存占用分析 1 影响因素概述2 前向计算临时Tensor显存占用2.1 self-attention显存占用2.2 MLP显存占用 3 梯度和优化器显存占用3.1 模型训练过程两者显存占用3.2 模型推理过程两者显存占用 1 影响因素概述 模型训练框架&#xff1a;例如pytorch框架的cuda context…...

Docker项目部署

目录 一、前端项目部署 1、上传文件 2、开启容器 3、测试 二、后端项目部署 1、打包java项目 2、将jar包和Dockerfile文件长传到Linux系统 3、构建镜像 4、开启容器 5、测试 三、DockerCompose快速部署 基本语法 一、前端项目部署 1、上传文件 里面包括页面和配置文…...

vue3实现文本超出鼠标移入的时候文本滚动

判断文本长度是否大于容器长度 鼠标移入的时候判断&#xff0c;此处使用了tailwindcss&#xff0c;注意一下要设置文本不换行。 <divref"functionsItems"mouseenter"enterFunctionsItem($event, index)"><img class"w-5 h-5" :src&quo…...

光伏系统MPPT、恒功率控制切换Simulink仿真

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

mysql双主互从通过KeepAlived虚拟IP实现高可用

mysql双主互从通过KeepAlived虚拟IP实现高可用 在mysql 双主互从的基础上&#xff0c; 架构图&#xff1a; Keepalived有两个主要的功能&#xff1a; 提供虚拟IP&#xff0c;实现双机热备通过LVS&#xff0c;实现负载均衡 安装 # 安装 yum -y install keepalived # 卸载 …...

​苹果应用高版本出现:“无法安装此app,因为无法验证其完整性”是怎么回事?竟然是错误的?

最近经常有同学私聊我问苹果应用签名后用落地页下载出现高版本是什么意思&#xff1f;我一脸懵&#xff01;还有这个操作&#xff1f;高版本是个啥玩意&#xff01;所以我就上了一下科技去搜索引擎搜索了下&#xff0c;哈哈哈&#xff0c;然后了解下来发现是这样的首先我们确定…...

AF_UNIX和127.0.0.1(AF_INET)回环地址写数据速度对比

在linux下&#xff0c;存在着这样的情况&#xff0c;本地的进程间通信&#xff0c;并且其中一个是服务端&#xff0c;另外的都是客户端。 服务端通过绑定端口&#xff0c;客户端往127.0.0.1的对应端口发送&#xff0c;即可办到&#xff0c;不过这样会浪费一个端口&#xff0c;同…...

我在 NPM 发布了新包: con-colors

链接地址&#xff1a;npmjs.com con-colors 安装依赖 yarn add con-colors使用 导入&#xff1a; import { print } from "con-colors";使用&#xff1a; print.succ("成功的消息"); print.err("失败的消息")例子&#xff1a; import { p…...

【python数据建模】Scipy库

常用模块列表 模块名功能scipy.constants数学常量scipy.fft离散傅里叶变换scipy.integrate积分scipy.interpolate插值scipy.interpolate线性代数scipy.cluster聚类分析、向量量化scipy.io数据输入输出scipy.misc图像处理scipy.ndimagen维图像scipy.odr正交距离回归scipy.optim…...

Keil调试器不为人知的秘密:用Command窗口实现自动化测试

Keil调试器不为人知的秘密&#xff1a;用Command窗口实现自动化测试 在嵌入式开发领域&#xff0c;Keil MDK作为一款广受欢迎的集成开发环境&#xff0c;其调试功能一直被工程师们频繁使用。然而&#xff0c;大多数开发者仅停留在基础断点调试的层面&#xff0c;对Command窗口这…...

AI绘画进阶:用Stable Diffusion的LoRA模型打造专属画风(附最新v4.10模型包)

AI绘画进阶&#xff1a;用Stable Diffusion的LoRA模型打造专属画风 最近在Civitai社区看到不少创作者用LoRA模型生成的惊艳作品——从赛博朋克风的城市夜景到水墨风格的奇幻角色&#xff0c;这些作品背后都离不开对LoRA模型的深度调校。作为SD玩家&#xff0c;掌握LoRA模型的运…...

RMBG-2.0创意应用:为LoRA训练准备高质量透明主体数据集方法

RMBG-2.0创意应用&#xff1a;为LoRA训练准备高质量透明主体数据集方法 1. 项目背景与价值 在AI图像生成领域&#xff0c;LoRA&#xff08;Low-Rank Adaptation&#xff09;训练已经成为个性化模型定制的重要技术。但要训练出高质量的LoRA模型&#xff0c;最关键的基础就是准…...

Qwen3-TTS-12Hz-1.7B-VoiceDesign C++接口开发:高性能语音合成引擎封装

Qwen3-TTS-12Hz-1.7B-VoiceDesign C接口开发&#xff1a;高性能语音合成引擎封装 1. 引言 语音合成技术正在快速发展&#xff0c;而Qwen3-TTS-12Hz-1.7B-VoiceDesign作为阿里云推出的先进语音生成模型&#xff0c;为开发者提供了强大的声音设计和控制能力。虽然官方提供了Pyt…...

Z-Image-Turbo-rinaiqiao-huiyewunv实操手册:Docker日志分级(INFO/WARN/ERROR)与问题定位指南

Z-Image-Turbo-rinaiqiao-huiyewunv实操手册&#xff1a;Docker日志分级&#xff08;INFO/WARN/ERROR&#xff09;与问题定位指南 1. 引言&#xff1a;为什么需要关注Docker日志&#xff1f; 当你兴致勃勃地部署了Z-Image-Turbo-rinaiqiao-huiyewunv这个专属二次元人物绘图工…...

Nunchaku FLUX.1 CustomV3效果展示:在4090上实现1024×1024图2.8秒内稳定出图

Nunchaku FLUX.1 CustomV3效果展示&#xff1a;在4090上实现10241024图2.8秒内稳定出图 1. 惊艳效果抢先看 Nunchaku FLUX.1 CustomV3带来的最直观感受就是&#xff1a;快&#xff01;真的快&#xff01;在RTX 4090显卡上&#xff0c;生成10241024分辨率的高清图片只需要2.8秒…...

在Ubuntu 18.04上搞定GAMMA遥感软件:从依赖库到加密狗驱动的保姆级避坑记录

在Ubuntu 18.04上搞定GAMMA遥感软件&#xff1a;从依赖库到加密狗驱动的保姆级避坑记录 如果你正在Ubuntu 18.04上尝试安装GAMMA遥感软件&#xff0c;那么这篇文章就是为你准备的。作为一名遥感领域的科研人员&#xff0c;我深知GAMMA软件在InSAR处理中的重要性&#xff0c;也体…...

车载以太网MACsec:构建安全通信的密钥体系与实战部署

1. 车载以太网MACsec&#xff1a;安全通信的基石 想象一下&#xff0c;你的爱车正在以100km/h的速度行驶&#xff0c;突然某个恶意黑客通过车载网络向刹车系统注入伪造指令——这种场景在智能网联时代绝非天方夜谭。车载以太网MACsec正是为防范这类威胁而生的安全卫士&#xff…...

从原理到实战:手把手构建哈夫曼压缩器

1. 为什么需要哈夫曼压缩 想象你每天都要给朋友发送大量短信&#xff0c;每条短信都要按字数计费。有一天你发现&#xff0c;某些词比如"好的"、"收到"出现的频率特别高&#xff0c;而"饕餮"、"魑魅"这类词几乎用不到。这时候你肯定会…...

Pikachu靶场实战:PHP反序列化漏洞代码审计与利用

1. PHP反序列化漏洞基础入门 第一次接触PHP反序列化漏洞时&#xff0c;我和大多数新手一样感到困惑&#xff1a;为什么把字符串转换成对象就能产生安全风险&#xff1f;这得从PHP的序列化机制说起。记得去年我在审计一个CMS系统时&#xff0c;就因为忽略了这个小功能导致整个系…...