C++—list类的使用及模拟实现

目录

1、list的介绍

2、list常用接口函数

2.1 几个构造函数

2.1.1 构造函数的模拟实现

2.2 迭代器

2.2.1 迭代器的模拟实现

2.3 容量相关的函数

3、list的增删查改

3.1 插入insert

3.2 删除erase

3.3 头插、头删、尾插、尾删

4、list需要注意的点及功能完善

4.1 list迭代器失效问题

4.2 list的sort排序


1、list的介绍

list在底层是双向链表,能够进行动态内存分配,与其他容器相比,list的插入删除要更高效。

list的特性

1、list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。

2、list的底层是带头双向循环链表结构,在节点中通过指针指向其前一个元素和后一个元素。

3、与其他的序列式容器相比(array,vector,deque等),list通常在任意位置进行插入、移除元素的效率更高。

list的缺陷

list最大的缺陷是不支持任意位置的随机访问

list和vector一样也是类模板。


2、list常用接口函数

2.1 几个构造函数

函数声明函数说明
list (size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造空的list
list (const list& x)拷贝构造函数
list (InputIterator first, InputIterator last)

用[first, last)区间中的元素构造list

注意:这里的区间是左闭右开

//无参构造
list<int> l1;
//用10个6初始化链表
list<int> l2(10, 6);
//拷贝构造
list<int> ll2(l2);vector<int> v{ 1,2,3,4 };
//用迭代器区间初始化链表
list<int> l3(v.begin(), v.end());

2.1.1 构造函数的模拟实现

无参构造

void empty_init()
{_head = new Node;_head->_next = _head;_head->_prev = _head;
}list()
{empty_init();
}

拷贝构造

list(const list<T>& lt)
{empty_init();for (const auto& e : lt){push_back(e);}
}

赋值构造

void swap(const list<T>& tmp)
{std::swap(_head, tmp._head);
}list<T>& operator=(const list<T> lt)
{swap(lt);return *this;
}

析构

void clear()
{iterator it = begin();while (it != end()){it = erase(it);}
}~list()
{clear();delete _head;_head = nullptr;
}

2.2 迭代器

可以暂时将迭代器理解成指针,这个指针指向list中的某个节点。

函数声明接口说明
begin + end返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin + rend返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置
vector<int> v1{ 5,3,10,26,9,22,12,24 };
list<int> l(v1.begin(), v1.end());auto it = l.begin();
while (it != l.end())
{cout << *it << " ";it++;
}

反向迭代

2.2.1 迭代器的模拟实现

与vector不同,list的迭代器不是一个原生指针,而是封装节点指针的类,因为用户只需要得到节点中的数据而不是整个节点。

vector随机访问可以支持像it+5,it[6]这样的形式,而list不能随机访问也就不能使用operator []来访问节点,仅支持++和--操作,这个++和--也不是指针的++和--,所以要把迭代器也封装成一个类,通过重载++、--和解引用等运算符来满足需求。

//先要封装一个结点类
template<class T>
struct ListNode
{ListNode<T>* _next;ListNode<T>* _prev;T _data;ListNode(const T& x = T()):_next(nullptr), _prev(nullptr), _data(x){}
};
//封装一个迭代器类
template<class T>
struct __list_iterator
{typedef ListNode<T> Node;typedef __list_iterator<T> self;Node* _node;__list_iterator(Node* x):_node(x){}self& operator++(){_node = _node->_next;return *this;}self operator++(int){//相当于__list_iterator<T> tmp(*this);self tmp(*this);_node = _node->_next;return tmp;}self& operator--(){_node = _node->_prev;return *this;}self operator--(int);//解引用重载T& operator*(){return _node->_data;}//T operator->(){return &_node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s);
};

迭代器的实现

const_iterator begin()const
{//这里是单参数类型支持隐式类型转换//return const_iterator(_head->_next);return _head->_next;
}const_iterator end()const
{return _head;
}iterator begin()
{return _head->_next;
}iterator end()
{return _head;
}

2.3 容量相关的函数

函数接口说明
empty检测list是否为空,是返回true,否则返回false
size返回list中有效节点的个数

这里个函数我们学会使用即可。

3、list的增删查改

访问头部和尾部数据

函数功能
front()取到头节点数据的引用
back()返回尾节点数据的引用

3.1 插入insert

iterator insert(iterator pos, const T& x)
{Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;++_size;//这里是为了管理_sizereturn newnode;
}

3.2 删除erase

将待删除的节点的前后节点先保存起来,再删除pos出节点,将前后节点连接起来。

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

3.3 头插、头删、尾插、尾删

//尾插
void push_back(const T& x)
{insert(end(), x);
}
//头插
void push_front(const T& x)
{insert(begin(), x);
}//尾删
void pop_back()
{erase(--end());
}//头删
void pop_front()
{erase(begin());
}

4、list需要注意的点及功能完善

4.1 list迭代器失效问题

list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,pos指向的节点的,改变的只是连接关系,位置始终都是一个位置。

只有在删除时才会失效,这个位置的数据被删除后,连接关系被改变,此位置就不在原链表中了,此时失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

4.2 list的sort排序

由于list是带头结点的双向循环链表,而算法库中的sort底层是快排,需要传入随机访问迭代器,所以list并不能使用算法库的sort。那么list的sort是怎么一回事呢?

list中给了一个适合自己的sort,这个sort实质上是归并排序,但是直接使用这个sort比list的数据先push_back到vector中,再使用算法库的sort,排完序后再导入list中的三步还要慢。

所以我们通常不使用list自己的sort。

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

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

相关文章

Mysql5.7-yum安装和更改mysql数据存放路径-2020年记录

记录下官网里用yum rpm源安装mysql, 1 官网下载rpm https://dev.mysql.com/downloads/repo/yum/ https://dev.mysql.com/doc/refman/5.7/en/linux-installation-yum-repo.html&#xff08;附官网操作手册&#xff09; wget https://repo.mysql.com//mysql80-community-release…

nvm list available为空

nvm list available为空 该问题主要是因为nvm 获取不到node导致&#xff0c;排查网络问题外&#xff0c;可能就是由于nvm环境变量配置问题导致&#xff0c;本次我这个问题就是由于环境变量配置缺少导致的。 第一步&#xff1a;排查并排除了网络问题。 第二步&#xff1a;排查环…

mosfet的驱动设计-栅极电阻

栅极电阻在MOSFET驱动电路中具有关键作用&#xff0c;其阻值直接影响器件开关速度、功率损耗及电磁干扰水平。本文将从物理原理出发&#xff0c;推导典型栅极电阻计算公式&#xff0c;并详细说明各参数选取依据。 本人查阅了很多资料&#xff0c;不同的资料介绍的计算方法也不尽…

Unity Dots从入门到精通之 Prefab引用 转 实体引用

文章目录 前言安装 DOTS 包实体引用Authoring 前言 DOTS&#xff08;面向数据的技术堆栈&#xff09;是一套由 Unity 提供支持的技术&#xff0c;用于提供高性能游戏开发解决方案&#xff0c;特别适合需要处理大量数据的游戏&#xff0c;例如大型开放世界游戏。 本文讲解我在…

并查集模板

注意理解路径压缩 static class UnionFind {int[] fa;public UnionFind(int n) {fa new int[n];for (int i 0; i < n; i) {fa[i] i;}}public int find(int i) {if (fa[i] ! i) {fa[i] find(fa[i]);}return fa[i];}public void union(int i, int j) {int fai find(i);in…

深入了解Linux —— 调试程序

前言 我们已经学习了linux下许多的工具&#xff0c;vim、gcc、make/makefile等&#xff1b; 已经能够在linux写代码&#xff0c;并且进行编译运行&#xff0c;让程序在linux下跑起来。 但是&#xff0c;如果我们在写代码的时候遇见了错误&#xff1b;但是我们并不知道错误在哪&…

Python接口自动化之断言封装!

该框架支持两种断言方式&#xff0c;相等和包含。 先看一下断言的yaml文件编写规范&#xff1a; validate: - equals: {status_code: 200} - contains: $ddt{assert_str} 其中assert_str和之前用例一样&#xff0c;作为变量&#xff0c;放在对应的data yaml文件中 # D…

基于Rye的Django项目通过Pyinstaller用Github工作流简单打包

前言 Rye的介绍和安装 Ryehttps://rye.astral.sh/Rye 完整使用教程_安装rye-CSDN博客https://blog.csdn.net/zhenndbc/article/details/144544692 正文 项目建立 配置好环境后 新建文件夹 新建文件夹&#xff0c;进入项目 初始化 rye init下载依赖 rye syncpycharm 打…

Pycharm 取消拼写错误检查(Typo:in word xxx)

现象 Pycharm显示单词存在错误&#xff0c;下面看着有下划波浪线&#xff0c;看着很不舒服。 快捷键AltEnter&#xff0c;查看提示错误。 Typo是啥? "Typo" 这个词通常用于描述打字或排印过程中的小错误&#xff0c;尤其是拼写错误。它指的是在文本中由于打字或印刷…

K8S学习之基础十七:k8s的蓝绿部署

蓝绿部署概述 ​ 蓝绿部署中&#xff0c;一共有两套系统&#xff0c;一套是正在提供服务的系统&#xff0c;一套是准备发布的系统。两套系统都是功能完善、正在运行的系统&#xff0c;只是版本和对外服务情况不同。 ​ 开发新版本&#xff0c;要用新版本替换线上的旧版本&…

三、0-1搭建springboot+vue3前后端分离-idea新建springboot项目

一、ideal新建项目1 ideal新建项目2 至此父项目就创建好了&#xff0c;下面创建多模块&#xff1a; 填好之后点击create 不删了&#xff0c;直接改包名&#xff0c;看自己喜欢 修改包名和启动类名&#xff1a; 打开ServiceApplication启动类&#xff0c;修改如下&#xff1a; …

任天堂Switch拉美游戏价涨,传Switch 2全球或提价

易采游戏网3月9日独家消息&#xff1a;近日据相关资讯显示&#xff0c;在拉丁美洲地区&#xff0c;任天堂Switch的游戏价格出现了上扬态势。这一变化引发了玩家与市场的关注&#xff0c;不过就目前而言&#xff0c;其并未波及全球游戏市场的整体定价格局。但值得注意的是&#…

10.2 继承与多态

文章目录 继承多态 继承 继承的作用是代码复用。派生类自动获得基类的除私有成员外的一切。基类描述一般特性&#xff0c;派生类提供更丰富的属性和行为。在构造派生类时&#xff0c;其基类构造函数先被调用&#xff0c;然后是派生类构造函数。在析构时顺序刚好相反。 // 基类…

如何在需求分析阶段考虑未来扩展性

在需求分析阶段考虑未来扩展性的关键在于 前瞻规划、灵活架构、标准设计。其中&#xff0c;前瞻规划尤为重要&#xff0c;因为通过全面分析业务发展趋势与技术演进&#xff0c;能够在初期设计阶段预留足够扩展空间&#xff0c;降低后期改造成本&#xff0c;为企业长期发展奠定坚…

PawSQL for MSSQL:PawSQL 支持 SQL Server 的SQL优化、SQL审核、性能巡检

0. 概述 在PawSQL的最新版本中&#xff0c;PawSQL 为 SQL Server 数据库提供了全方位的SQL优化、SQL审核、性能巡检支持&#xff0c;覆盖SQL开发、测试、运维的整个生命周期&#xff0c;助力用户充分发挥 SQL Server 数据库的性能潜力。 1. 纳管SQL Server 实例 工作空间是SQ…

【Java代码审计 | 第六篇】XSS防范

文章目录 XSS防范使用HTML转义使用Content Security Policy (CSP)输入验证使用安全的库和框架避免直接使用用户输入构建JavaScript代码 XSS防范 使用HTML转义 在输出用户输入时&#xff0c;对特殊字符进行转义&#xff0c;防止它们被解释为HTML或JavaScript代码。 例如&…

NO.26十六届蓝桥杯备战|字符数组七道练习|islower|isupper|tolower|toupper|strstr(C++)

P5733 【深基6.例1】自动修正 - 洛谷 小写字母 - 32 大写字母 大写字母 32 小写字母 #include <bits/stdc.h> using namespace std;const int N 110; char a[N] { 0 };int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cin >> a;int i 0;while (a…

langChainv0.3学习笔记(初级篇)

LangChain自0.1版本发布以来&#xff0c;已经历了显著的进化&#xff0c;特别是向AI时代的适应性提升。在0.1版本中&#xff0c;LangChain主要聚焦于提供基本的链式操作和工具集成&#xff0c;帮助开发者构建简单的语言模型应用。该版本适用于处理简单任务&#xff0c;但在应对…

qt 播放pcm音频

一、获取PCM音频 ffmpeg -i input.mp3 -acodec pcm_s16le -ar 44100 -ac 2 -f s16le output.pcm -acodec pcm_s16le&#xff1a;指定16位小端PCM编码格式&#xff08;兼容性最佳&#xff09;-ar 44100&#xff1a;设置采样率为CD标准44.1kHz&#xff08;可替换为16000/8000等&a…

Windsuf 连接失败问题:[unavailable] unavailable: dial tcp...

问题描述 3月6日&#xff0c;在使用Windsuf 时&#xff0c;遇到以下网络连接错误&#xff1a; [unavailable] unavailable: dial tcp 35.223.238.178:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of…