讨论stl链表

讨论链表

  • list迭代器失效
  • list的模拟实现
    • 创建结点类
    • 链表迭代器
    • 完成实现代码
  • list与vector

链表是一个序列容器,在任意位置都可以用常数时间插入或者删除,并且可以在两个方向进行迭代。

链表定义

list迭代器失效

迭代器失效指迭代器所指向的结点无效,即该结点被删除了。

  • list的底层结构是双向带头循环链表,因此向list中插入数据是不会造成迭代器失效。
  • 但删除数据时,指向删除结点的迭代器会失效,其他迭代器不会受影响。

list的模拟实现

创建结点类

  • 链表是由一个一个结点组成,结点中存放储存的元素已经指向下一个以及前一个的指针。
template<class T>
struct list_node {T _val;list_node<T> *_prev;list_node<T> *_next;list_node(const T &val = T()): _val(val), _prev(nullptr), _next(nullptr) {}
};

链表迭代器

  • 链表的迭代器不同于顺序表。顺序表的迭代器可以直接返回头部和尾部指针的位置。++操作只需要移动相应字节数的指针即可完成。

顺序表迭代器

  • 链表迭代器++操作不能依靠简单的指针++完成,因为不是连续空间,因此需要封装一层结点结构,以_node = _node->next来达到++的效果。
template<class T, class Ref, class Ptr>
struct __list_iterator {typedef list_node<T> node;typedef __list_iterator<T, Ref, Ptr> self;node *_node;__list_iterator(node *node = nullptr): _node(node) {}self &operator++() {_node = _node->_next;return *this;}self operator++(int) {self tmp(*this);_node = _node->next;return tmp;}self &operator--() {_node = _node->_prev;return *this;}self operator--(int) {self tmp(*this);_node = _node->_prev;return tmp;}Ref operator*() {return _node->_val;}Ptr operator->() {return &_node->_val;}bool operator!=(const self &s) {return _node != s._node;}bool operator==(const self &s) {return _node == s._node;}
};
  • 其中RefPtr模板为传入引用或者指针对象区分const和非const的模板。

完成实现代码

namespace max {template<class T>struct list_node {T _val;list_node<T> *_prev;list_node<T> *_next;list_node(const T &val = T()): _val(val), _prev(nullptr), _next(nullptr) {}};// 迭代器封装template<class T, class Ref, class Ptr>struct __list_iterator {typedef list_node<T> node;typedef __list_iterator<T, Ref, Ptr> self;node *_node;__list_iterator(node *node = nullptr): _node(node) {}self &operator++() {_node = _node->_next;return *this;}self operator++(int) {self tmp(*this);_node = _node->next;return tmp;}self &operator--() {_node = _node->_prev;return *this;}self operator--(int) {self tmp(*this);_node = _node->_prev;return tmp;}Ref operator*() {return _node->_val;}Ptr operator->() {return &_node->_val;}bool operator!=(const self &s) {return _node != s._node;}bool operator==(const self &s) {return _node == s._node;}};template<class T>class list {typedef list_node<T> node;typedef __list_iterator<T, T &, T *> iterator;typedef __list_iterator<T, const T &, const T *> const_iterator;public:void empty_init() {_head = new node();_head->_next = _head;_head->_prev = _head;_size = 0;}list() {empty_init();}list(int n, const T &val = T()) {empty_init();for (int i = 0; i < n; ++i) {push_back(val);}}template<class Iterator>list(Iterator first, Iterator last) {empty_init();while (first != last) {push_back(*first);++first;++_size;}}list(const list<T> &lt) {empty_init();for (auto e: lt) {push_back(e);}}void swap(list<T> &tmp) {std::swap(_head, tmp._head);std::swap(_size, tmp._size);}list<T> &operator=(list<T> tmp) {swap(tmp);return *this;}~list() {clear();delete _head;_head = nullptr;}void push_back(const T &val) {node *newNode = new node(val);node *end = _head->_prev;end->_next = newNode;newNode->_prev = end;newNode->_next = _head;_head->_prev = newNode;++_size;}void push_front(const T &val) {node *newNode = new node(val);node *next = _head->_next;newNode->_next = next;next->_prev = newNode;_head->_next = newNode;newNode->_prev = _head;}void pop_back() {assert(_head->_next != _head);node *del = _head->_prev;_head->_prev = del->_prev;del->_prev->_next = _head;delete del;del = nullptr;--_size;}void pop_front() {assert(_head->_next != _head);node *del = _head->_next;_head->_next = del->_next;del->_next->_prev = _head;delete del;del = nullptr;--_size;}iterator begin() {return iterator(_head->_next);}iterator end() {return iterator(_head);}const_iterator begin() const {return const_iterator(_head->_next);}const_iterator end() const {return const_iterator(_head);}iterator insert(iterator pos, const T &val) {node *newNode = new node(val);node *prev = pos._node->_prev;prev->next = newNode;newNode->_prev = prev;newNode->_next = pos._node;pos._node->_prev = newNode;++_size;return iterator(newNode);}iterator erase(iterator pos) {assert(_head != _head->_next);node *cur = pos._node;node *next = cur->_next;node *prev = cur->_prev;prev->_next = next;next->_prev = prev;delete cur;cur = nullptr;--_size;return iterator(next);}void clear() {iterator it = begin();while (it != end()) {it = erase(it);--_size;}}size_t size() const {return _size;}private:node *_head;size_t _size;};
}

list与vector

  • vectorlist底层结构不同,因此在使用场景上存在一定差异。
vectorlist
底层结构动态顺序表,一段连续的空间。带头双向循环链表
随机访问支持随机访问,效率为O(1)。不支持随机访问,访问某个元素的效率为O(N)。
插入和删除尾插和尾删时效率是O(1)。除此之外插入删除的效率都很低,因为需要移动数据,若插入大量数据还涉及到扩容,异地扩容需要拷贝元素和释放旧空间,效率很低。任意位置插入和删除数据效率为O(1)。不需要移动数据。
空间利用率底层为连续空间,不容易产生内存碎片,利用率高,缓存利用率高。底层为动态开辟的小结点,容易造成内存碎片,空间利用率低,缓存利用率低。
迭代器原生态指针。对原生态指针进行封装。
迭代器失效插入元素时可能会造成迭代器失效,因为可能会异地扩容。删除元素时当前迭代器会失效。插入元素时不会造成迭代器失效,删除元素时会造成当前迭代器失效,其他迭代器不受影响。

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

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

相关文章

淘宝扭蛋机小程序开发:为消费者带来新的潮玩乐趣

在当下的消费市场&#xff0c;潮玩消费已经成为了年轻人的新宠&#xff0c;预计在近几年间潮玩市场的销售额将达到千亿元&#xff01;其中扭蛋机市场更是吸引了各个阶段的消费群体&#xff0c;在市场巨大的发展前景下&#xff0c;同时也吸引了众多投资者入局&#xff0c;市场竞…

SuperMap iDesktop

SuperMap iDesktop 介绍 SuperMap iDesktop是一款由超图公司推出的企业级插件式桌面GIS软件&#xff0c;它通过SuperMap iObjects .NET、桌面核心库和.NET Framework 4.0构建&#xff0c;集成了地图制作、空间分析、数据编辑、三维分析等多种功能于一体&#xff0c;为用户提供…

el-date-picker限制开始时间不能大于结束时间,且结束不能小于开始时间

<div class"des-status-df">开始</div><div class"block"><el-date-picker:picker-options"startDatePicker"v-model"startTime"type"datetime"placeholder"选择日期时间"></el-date-…

标准版回收站的商品怎么删除?

管理后台/维护/数据维护/清除数据 里面就可以清空回收站的商品

深度解析:scikit-learn Pipeline记忆功能的秘密

标题&#xff1a;深度解析&#xff1a;scikit-learn Pipeline记忆功能的秘密 摘要 scikit-learn&#xff08;简称sklearn&#xff09;是Python中一个广泛使用的机器学习库&#xff0c;它提供了许多用于数据挖掘和数据分析的工具。Pipeline是sklearn中一个强大的功能&#xff…

Qt---xxx.pro: Missing closing brace(s).

丢失了关闭括号 出现这个问题&#xff0c;可以找一下pro文件中是不是少括号了。 CONFIG(debug, debug|release) {TARGET $$join(TARGET,,,d)ROUTDIR $$PWD/../build/debug } else {TARGET $$join(TARGET,,,)ROUTDIR $$PWD/../build/release 我本来是这么写的&#xff0c…

Postman自动化测试实战:使用脚本提升测试效率

在软件开发过程中&#xff0c;接口测试是确保后端服务稳定性和可靠性的关键步骤。Postman作为一个流行的API开发工具&#xff0c;提供了强大的脚本功能来实现自动化测试。通过在Postman中使用脚本&#xff0c;测试人员可以编写测试逻辑&#xff0c;实现测试用例的自动化执行&am…

Flink作业执行之 4.JobGraph

Flink作业执行之 4.JobGraph 1. 入口 前文了解了由Transformation到StreamGraph的过程&#xff0c;StreamGraph即作业的逻辑拓扑结构。 生成逻辑结构后&#xff0c;接下来的操作往往是对逻辑结构的优化。在很多组件中都是这样的处理&#xff0c;如hive、spark等都会执行“逻辑…

C++中main函数的参数、返回值分别什么意思?main函数返回值跟普通函数返回值一样吗?

在C中&#xff0c;main函数是程序的入口点&#xff0c;即程序开始执行的地方。main函数可以有两种形式的签名&#xff08;signature&#xff09;&#xff1a; 标准的main函数&#xff0c;不接受任何参数&#xff0c;也不返回任何值&#xff1a; int main() {// 代码... }带有参…

os实训课程模拟考试(选择题复习)

目录 一、操作系统的基本功能和设计目标 &#xff08;1&#xff09;基础知识 &#xff08;2&#xff09;题目与答案 1、操作系统是一组 B &#xff08;单选&#xff09; 2、以下哪项不是操作系统关心的主要问题&#xff1f;D &#xff08;单选&#xff09; 3、下列关于…

使用SpringBoot整合filter

SpringBoot整合filter&#xff0c;和整合servlet类似&#xff0c;也有两种玩儿法 1、创建一个SpringBoot工程&#xff0c;在工程中创建一个filter过滤器&#xff0c;然后用注解WebFilter配置拦截的映射 2、启动类还是使用ServletComponentScan注解来扫描拦截器注解WebFilter 另…

京品优送元宇宙

在科技飞速发展的今天&#xff0c;我们的生活方式正在发生深刻的变化。其中&#xff0c;京品优送元宇宙的崛起&#xff0c;为我们带来了全新的购物体验和生活方式。京品优送&#xff0c;作为一家领先的科技物流企业&#xff0c;不仅仅满足于现实世界的快递服务&#xff0c;更是…

Selenium 库

Selenium两大对象 WebDriver对象 页面跳转截图获取源码执行js最大化窗口切换窗口 WebElement对象 输入点击获取内容获取属性改变样式 鼠标和键盘操作 鼠标 左键单击右键单击左键双击右键双击中键单击、双击滚动长按拖动 按键&#xff1a; ASCII功能键编辑键快捷键 快…

Windows系统开启自带虚拟机功能Hyper-V

前言 最近有小伙伴咨询&#xff1a;Windows系统上有自带的虚拟机软件吗&#xff1f; 答案肯定是有的。它就是Hyper-V&#xff0c;但很多小伙伴都不知道怎么打开这个功能。 今天小白就带大家来看看如何正确打开这个Windows自带的虚拟机功能Hyper-V。 开始之前&#xff0c;你…

基于Spring Boot与Vue的智能房产匹配平台+文档

博主介绍&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐&#xff1a;最热的500个选题…

学会python——在Excel中生成图表数据(python实例十五)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.生成表格数据 3.1 代码构思 3.2 代码示例 4.绘制图表 4.1 代码构思 4.2 代码示例 5.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 P…

Shell 脚本编程保姆级教程(下)

七、Shell 流程控制 7.1 if #!/bin/bash num1100 if test $[num1] 100 thenecho num1 是 100 fi 7.2 if else #!/bin/bash num1100 num2100 if test $[num1] -eq $[num2] thenecho 两个数相等&#xff01; elseecho 两个数不相等&#xff01; fi 7.3 if else-if else #!/…

电影APP——项目建议书参考

项目建议书 1. 前言1.1 实现目标1.2 项目应用范围1.3 项目名称 2. 概述2.1 国内外发展综述2.2 拟解决的问题2.2.1 业务问题2.2.2 技术需求 2.3 系统环境需求2.3.1 网络需求描述2.3.2 业务需求描述2.3.3 运行环境/用户描述 2.4 功能建议2.4.1应用场景描述2.4.2功能划分/功能模型…

数据仓库、数据湖的异同

数据仓库与数据湖&#xff0c;作为数据存储与管理的两大重要工具&#xff0c;各有其独特之处&#xff0c;同时也存在着一定的交集。在深入探讨这两者的异同之前&#xff0c;我们先来明确它们的核心定义与功能。 数据仓库&#xff0c;这一名词早已深入人心&#xff0c;其核心理…

性能之巅的巴比达内网穿透访问单位的web管理系统

在这个数字化飞速发展的时代&#xff0c;作为一名IT部门的小主管&#xff0c;我经常面临着一项挑战&#xff1a;如何在外网环境下高效、安全地访问我们单位内部部署的Web管理系统。这不仅仅是关乎我个人的工作效率&#xff0c;更是影响到整个团队能否快速响应市场需求的关键。直…