C++ List (带你一篇文章搞定C++中的List类)

感谢大佬的光临各位,希望和大家一起进步,望得到你的三连,互三支持,一起进步

数据结构习题_LaNzikinh篮子的博客-CSDN博客

初阶数据结构_LaNzikinh篮子的博客-CSDN博客

收入专栏:C++_LaNzikinh篮子的博客-CSDN博客

其他专栏:c语言基础_LaNzikinh篮子的博客-CSDN博客

个人主页:LaNzikinh-CSDN博客

文章目录

  • 前言
  • 一.迭代器
  • 二.list的底层实现
  • 三.list使用和细节
  • 总结

前言

经过前面两个容器的讲解,其实已经对很多接口的使用都了解的差不多了,容器之间接口的使用真的都是大体相同的,但是底层的实现是不同的,今天我们来看看列表是如何实现这个功能的,在讲解列表的实现之前,我们先要再次来讲解这个迭代器


一.迭代器

迭代器的功能分为四种迭代器,反向迭代器,常数迭代器,反向常数迭代器,他的性质有三种,单向迭代器,双向迭代器和随机迭代器,性质的意思就是底层结构,底层结构可以决定可以用哪些算法

举个例子来说,比如说我们之前学过的排序算法,他在库里面就一个专门这样子的函数sort,他支持的就是随机的代替其他不支持,所以说在list创建的类就不能用这个库里面的算法,只能自己实现一个,又比如说逆置算法reverse(需要++/--)他支持双向迭代器,所以说随机的也可以,但是单向的就不行

我们的list就是双向迭代器,我们之前学过的vector和string就是随机迭代器,那我们后面的栈和队列是什么呢?

答案是根本不支持迭代,栈的特性是先进后出,队列的特性是先进先出,如果都满足了迭代器的遍历,那这些特性就不存在了,你支持了迭代器,那你的特性的意义在什么地方呢

二.list的底层实现

我们之前讲过了库函数的使用,直接看文档即可,在这里就不做多的了解了,和之前的使用string,vector是大致相同的,主要还是来看list的底层,他是一个带头双向循环列表,不是我们以前C语言学过的单链表

接下来了,我们先要来定义两个结构体,一个就是节点本身,还有一个就是指向节点的指针,即便它是一个带头双向循环列表,这两个也是必不可少的

2.1定义两个结构体

结点

const T& data = T();利用缺省参数来进行初始化

template<class T>
struct list_node
{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& data = T()):_data(data), _next(nullptr), _prev(nullptr){}
};

指向节点的指针

注意:这里获取的迭代器,就是一个节点的指针

因为他是一个指针,所以说我们要用函数重载来定义它的加加减减和判断等于,还有解引用

template<class T>
struct list_iterator
{typedef list_node<T> Node;typedef list_iterator<T> Self;Node* _node;list_iterator(Node* node):_node(node){}T& operator*(){return _node->_data;}Self& operator++(){_node = _node->_next;return *this;}Self& operator--(){_node = _node->_prev;return *this;}bool operator!=(const Self& s) const{return _node != s._node;}bool operator==(const Self& s) const{return _node == s._node;}
};

2.2insert()和 erase()

迭代器失效问题

前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

insert()

void insert(iterator pos, const T& x)
{Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);// prev newnode curnewnode->_next = cur;cur->_prev = newnode;newnode->_prev = prev;prev->_next = newnode;++_size;
}

erase()

只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响

void erase(iterator pos)
{assert(pos != end());Node* prev = pos._node->_prev;Node* next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;--_size;
}

所以要用返回值来改正,防止迭代器失效

int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
list<int> l(array, array+sizeof(array)/sizeof(array[0]));
auto it = l.begin();
while (it != l.end())
{
l.erase(it++); // it = l.erase(it);
}

2.3头插尾插一个数据

直接复用就可以了

void push_back(const T& x)
{insert(end(), x);
}void push_front(const T& x)
{insert(begin(), x);
}

2.4析构函数和迭代器函数

iterator begin()
{return _head->_next;
}iterator end()
{return _head;
}list()
{_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;
}

2.4成员对象

private:Node* _head;size_t _size;

三.list使用和细节

还是补充几个list一些独特的函数使用方式和一些使用它的细节

emplace:构造和插入元素

他是支持直接传构造函数对象的参数的

list<A> lt;
A a1(1,1);
lt.push_back(3,3);//不合理,不存在
lt.emplace_back(3,3);//可以

unique:删除重复值

注意:前提要有序不然删不完全

merge:合并排序列表

注意:合并排序列表,v1会被滞空

it.merge(v1);

补:

如果要在pos的位置插入一个30大小的元素

auto it = lt.begin();
int k = 3;
while (k--)
{++*it;
}
it.insert(it, 30);

因为他的迭代器只支持++


总结

链表容器结构到这里就结束了,下一章,我们将引入一个适配器的概念去完成栈与队列的知识

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

9.1 溪降技术:游泳

目录 9.1 游泳概述观看视频课程电子书&#xff1a;游泳防御性游泳姿势**身体姿势** 积极游泳姿势**身体姿势** 总结 9.1 游泳 概述 深潭游泳 对于峡谷探险者来说&#xff0c;游泳是一项核心技能。我们的游泳水平和自信心将在很大程度上决定我们的路线选择。在这一阶段&#xff…

【Head-DETR系列(7)】DETR 代码分析

在nuscens数据集上&#xff0c; Results and Models BackboneModelLr schdMem (GB)Inf time (fps)box APConfigDownloadR-50DETR150e7.940.1configmodel | log 我们先看检测器 /mmdetection-2.28.2/mmdet/models/detectors/detr.py def forward_train(self,img,img_metas,gt_…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0918)

十二、首页 layout 架子 [element-plus 菜单] 基本架子拆解 架子组件列表&#xff1a; el-container el-aside 左侧 el-menu 左侧边栏菜单 el-container 右侧 el-header 右侧头部 el-dropdown el-main 右侧主体 router-view <script setup> import {Management,Pr…

【C++篇】C++类与对象深度解析(三):类的默认成员函数详解

文章目录 【C篇】C类与对象深度解析&#xff08;三&#xff09;前言4. 运算符重载基本概念4.1 运算符重载的基本概念4.2 重载运算符的规则4.3 成员函数重载运算符4.4 运算符重载的优先级与结合性4.5 运算符重载中的限制与特殊情况4.5.1 不能创建新的操作符4.5.2 无法重载的运算…

影刀RPE学习——自动化

下载网址&#xff1a;影刀RPA - 影刀官网 (yingdao.com) 傻瓜式安装进入界面&#xff1a; 官方教程&#xff1a;影刀RPA零基础入门教程&#xff08;2024最新版&#xff09;&#xff1a;01 引入课-影刀初相识_哔哩哔哩_bilibili

我的AI工具箱Tauri版-VideoMusicCheckpointLouver音乐卡点百叶窗视频制作

本教程基于自研的AI工具箱Tauri版进行VideoMusicCheckpointLouver音乐卡点百叶窗视频制作。 视频样片《队长小翼》《沖田浩之-燃えてヒーロー》百叶窗卡点视频 《队长小翼》《沖田浩之-燃えてヒーロー》百叶窗卡点视频 该模块没有任何消耗。需要提前准备好响应的素材 该模块没…

物联网系统中环境监测设备如何检测PM2.5——快速了解粉尘传感器

物联网系统中为什么要使用粉尘传感器 物联网系统中使用粉尘传感器的原因是多方面的&#xff0c;主要体现在以下几个方面&#xff1a; 空气质量监测 保障公众健康&#xff1a;粉尘传感器能够实时监测空气中粉尘颗粒的浓度&#xff0c;特别是PM2.5和PM10等可吸入颗粒物&#xff…

【C语言零基础入门篇 - 6】:数组、字符和字符串带你探索无限可能

文章目录 数组一维数组一维数组的定义一维数组的初始化 字符数组二维数组二维数组存汉字 字符串相关函数小结 数组 特点&#xff1a; 在同一个数组中&#xff0c;所有元素都是同一个类型。可以是int、char、float、double等类型。数组是一种构造类型&#xff0c;是一批数据的…

Android14请求动态申请存储权限

Android14请求动态申请存储权限 Android14和Android15存储权限有增加多了选择部分&#xff0c;还是全部。一个小小的存储权限真的被它玩出了花来。本来Android13就将存储权限进行了3个细分&#xff0c;是图片&#xff0c;音频还是视频文件。 步骤一&#xff1a;AndroidManife…

替西帕肽;Mounjaro;Tirzepatide;CAS:2023788-19-2

【替西帕肽Tirzepatide 简介】 替西帕肽是一种GIP/GLP-1受体激动剂&#xff0c;由39个氨基酸的多肽组成。Tirzepatide (LY3298176) 是葡萄糖依赖性胰岛素营养多肽 (GIP) 和胰高血糖素样肽-1 (GLP-1) 受体双重激动剂。Tirzepatide (LY3298176) 在血糖控制和体重减轻方面的疗效明…

Acwing数据结构:单链表

单链表 主要思想&#xff1a;使用数组实现链表(而不用结构体&#xff0c;结构体代码更长&#xff0c;后续图论也是基于数组实现&#xff09;&#xff0c;即静态链表。因为动态链表使用new申请空间需要较多的时间&#xff0c;而算法要求的是以较少的时间完成任务。 单链表&…

【软件设计文档】概要设计说明书、详细设计说明书、需求分析文档,需求报告,测试报告等

1引言 1.1编写目的 1.2项目背景 1.3参考资料 2系统总体设计 2.1整体架构 2.2整体功能架构 2.3整体技术架构 2.4运行环境设计 2.5设计目标 3系统功能模块设计 3.1个人办公 4性能设计 4.1响应时间 4.2并发用户数 5接口设计 5.1接口设计原则 5.2接口实现方式 6运行设计 6.1运行模块…

软考中级软件设计师——知识产权学习记录

软考中级软件设计师——知识产权 著作权人身权著作财产权著作权侵权行为 计算机软件著作权基本知识计算机软件著作权侵权 专利地域性与专利权申请基本知识专利权侵权 职务作品委托开发商业秘密权基本知识商业秘密侵权 商标权与商标注册基本知识商标权侵权 著作权 著作权也称为…

大数据-138 - ClickHouse 集群 表引擎详解3 - MergeTree 存储结构 数据标记 分区 索引 标记 压缩协同

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

阻止冒泡事件

每一div都有一个切换事件 div里包括【复制】事件&#xff0c; 点击【复制按钮】&#xff0c;会触发【切换事件】 因为冒泡 在 Vue 3 中&#xff0c;阻止 click 事件冒泡可以使用以下常规方法&#xff1a; 1 事件修饰符&#xff1a;Vue 3 中提供了多种事件修饰符&#xff0c…

第14章 存储器的保护

第14章 存储器的保护 该章主要介绍了GDT、代码段、数据段、栈段等的访问保护机制。 存储器的保护功能可以禁止程序的非法内存访问。利用存储器的保护功能&#xff0c;也可以实现一些有价值的功能&#xff0c;比如虚拟内存管理。 代码清单14-1 该章节的代码主要实现的功能就…

科学哲学(Philosophy of Science)

GPT-4o (OpenAI) 科学哲学是一门研究科学的基本问题和本质的哲学学科&#xff0c;探讨科学方法、科学知识的性质、科学理论的发展及科学实践的意义和价值等问题。以下是科学哲学的一些关键方面和概念&#xff1a; 主要问题和概念&#xff1a; 1. 科学方法论&#xff1a; - …

大模型研发全揭秘:如何通过模型验证提升模型性能?(附详细代码)

在机器学习和深度学习的开发流程中&#xff0c;模型验证是一个关键的环节。验证集不仅用于检查模型的性能&#xff0c;还能帮助识别和解决潜在问题。本文将通过详细的代码示例和具体案例&#xff0c;逐步介绍从验证集准备、模型测试到评估指标计算的全过程。无论你是AI新手还是…

路由器接口配置DHCP实验简述

一、路由器配置 [Huawei]undo info-center enable Info: Information center is disabled. [DHCP-SERVER]sysname DHCP-Server [DHCP-Server]dis this sysname DHCP-Server undo info-center enable return [DHCP-Server]dhcp enable Info: The operation may take a few secon…

C++速通LeetCode简单第17题-爬楼梯(全网最简单)

思路要点&#xff1a;将问题转化为求斐波那契数列的第n项&#xff0c;然后迭代。 思路分析&#xff1a;最后一次爬的阶数不是1就是2&#xff0c;假设爬n阶的方法数是f(n)&#xff0c;假设最后一次爬1阶&#xff0c;那么爬前面的 n-1阶的方法数是f(n-1)&#xff1b;假设最后一次…