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.rhkb.cn/news/426176.html

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

相关文章

flask项目初始化

1、初始环境 python3.8 2、flask文档地址&#xff1a;https://flask.palletsprojects.com/en/latest/installation/#install-flask 3、初始化项目 $ mkdir myproject $ cd myproject $ python3 -m venv .venv $ . .venv/bin/activate $ pip install Flask4、打开项目mypr…

Pycharm出现Please specify a different SDK name报错,但是看不到重名环境解决方案

这句话的意思是出现了重名的环境 &#xff0c;一般情况下删除重名的环境即可解决问题。做法如下图所示 1&#xff0c;点击右上角齿轮→settings&#xff08;或者File→settings&#xff09;进入Python Interpreter 2.点击这个沙漏按键&#xff0c;你会发现多了几个环境&#x…

VScode相关问题与解决

VScode只是一个文档编辑器&#xff0c;类似于我们使用的记事本。我们在编辑完文档之后呢一定要保存。 文档编辑器加上它可以安装不同的插件&#xff0c;就可以进行程序开发。 1.写c文件时找不到头文件stdio.h 在linux下我们gcc命令来编译c文件时&#xff0c;会遇到找不到头文…

一文讲懂Mac中的环境变量

你是否曾经因为环境变量配置不当而浪费了宝贵的开发时间?你是否好奇为什么有时候在终端输入命令会提示"command not found",而有时候又能正常运行?如果你是一名Mac用户,并且希望真正掌握环境变量的奥秘,那么这篇文章将为你揭开Mac中环境变量的神秘面纱,帮助你成为一…

Java设计模式—面向对象设计原则(二) --------> 里氏代换原则 LSP (完整详解,附有代码+案列)

文章目录 里氏代换原则3.2.1 概述3.2.2 改进上述代码 里氏代换原则 里氏代换原则&#xff1a;Liskov Substitution Principle&#xff0c;LSP 3.2.1 概述 里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则&#xff1a;任何基类可以出现的地方&#xff0c;子类一定…

html实现好看的多种风格手风琴折叠菜单效果合集(附源码)

文章目录 1.设计来源1.1 风格1 -图文结合手风琴1.2 风格2 - 纯图片手风琴1.3 风格3 - 导航手风琴1.4 风格4 - 双图手风琴1.5 风格5 - 综合手风琴1.6 风格6 - 简描手风琴1.7 风格7 - 功能手风琴1.8 风格8 - 全屏手风琴1.9 风格9 - 全屏灵活手风琴 2.效果和源码2.1 动态效果2.2 源…

FloodFill(洪水灌溉)算法专题——DFS深搜篇

目录 1、图像渲染 1.1 算法原理 1.2 算法代码 2、岛屿数量 2.1 算法原理 2.2 算法代码 3、岛屿的最大面积 3.1 算法原理 3.2 算法代码 4、被围绕的区域 4.1 算法原理 4.2 算法代码 5、太平洋大西洋水流问题 5.1 算法原理 5.2 算法代码 6、扫雷游戏 6.1 算法原理…

React学习day07-ReactRouter-抽象路由模块、路由导航、路由导航传参、嵌套路由、默认二级路由的设置、两种路由模式

14、ReactRouter续 &#xff08;2&#xff09;抽象路由模块 1&#xff09;新建page文件夹&#xff0c;存放组件 组件内容&#xff1a; 2&#xff09;新建router文件夹&#xff0c;在其下创建实例 3&#xff09;实例导入&#xff0c;使用 4&#xff09;效果 &#xff08;3&…

【大数据方案】智慧大数据平台总体建设方案书(word原件)

第1章 总体说明 1.1 建设背景 1.2 建设目标 1.3 项目建设主要内容 1.4 设计原则 第2章 对项目的理解 2.1 现状分析 2.2 业务需求分析 2.3 功能需求分析 第3章 大数据平台建设方案 3.1 大数据平台总体设计 3.2 大数据平台功能设计 3.3 平台应用 第4章 政策标准保障体系 4.1 政策…

Day26_0.1基础学习MATLAB学习小技巧总结(26)——数据插值

利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍&#xff0c;为了在这个过程中加深印象&#xff0c;也为了能够有所足迹&#xff0c;我会把自己的学习总结发在专栏中&#xff0c;以便学习交流。 参考书目&#xff1a; 1、《MATLAB基础教程 (第三版) (薛山)》 2、《MATL…

Java项目——苍穹外卖(二)

Redis 简介 Redis是一个基于内存的key-value结构数据库 基于内存存储&#xff0c;读写性能高适合存储热点数据&#xff08;热点商品、资讯、新闻&#xff09;企业应用广泛 基础操作 启动 在redis安装目录中打开cmd&#xff0c;输入如上图指令即可启动&#xff0c;按下crtl…

【图像匹配】基于SIFT算法的图像匹配,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于基于SIFT算法的图像匹配&#xff0c;用matlab实现。 一、案例背景和算法介绍 本…

es的封装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、类和接口介绍0.封装思想1.es的操作分类 二、创建索引1.成员变量2.构造函数2.添加字段3.发送请求4.创建索引总体代码 三.插入数据四.删除数据五.查询数据 前…

Linux下root用户共享conda环境给其他用户

首先可以先用命令查看环境存储位置 conda env list 比如我的root用户的base环境 # conda environments: # base * /usr/local/miniconda3 在root下先给环境添文件夹加普通用户的权限 chmod -R 755 /usr/local/miniconda3 接下来新建一个用户&#xff0…

Python 课程14-TensorFlow

前言 TensorFlow 是由 Google 开发的一个开源深度学习框架&#xff0c;广泛应用于机器学习和人工智能领域。它具有强大的计算能力&#xff0c;能够运行在 CPU、GPU 甚至 TPU 上&#xff0c;适用于从小型模型到大规模生产系统的各种应用场景。通过 TensorFlow&#xff0c;你可以…

Unity+LeapMotion2的使用

开始吧 导入步骤1.到官网下载软件并安装2.安装插件3.场景中添加检测管理器4.场景中添加手部模型 更多细节 导入步骤 1.到官网下载软件并安装 地址 重启电脑后连接设备 可以看到连接成功 2.安装插件 &#xff08;也可以看官方教程&#xff09; Project—>PackageManag…

从AI应用排行榜选择AI产品(9月)

2024年9月13日&#xff0c;OpenAI公司宣布推出其全新的AI模型&#xff1a;o1&#xff0c;在数学、编程和科学问题的解决处理能力上取得了显著进步。该模型通过自我对弈强化学习&#xff08;Self-play RL&#xff09;和思维链&#xff08;Chain of Thought, CoT&#xff09;技术…

openssl的使用

1、编译 Github下载&#xff1a;https://github.com/openssl/openssl 官网下载&#xff1a;https://openssl-library.org/source/index.html 官网历史版本&#xff1a;https://www.openssl.org/source/old/ 1.1 Windows下编译 我的文章&#xff1a;OPC UA使用 Openssl库编译…

0基础带你入门Linux之使用

1.Ubuntu软件管理 回顾一下&#xff0c;我们之前使用su root切换到root模式&#xff0c;使用who 发现为什么显示的还是bd用户呢&#xff1f;为什么呢&#xff1f; 这个who是主要来查看的是我们登录的时候是以什么用户登录的 所以即使我们使用who进行查看的时候显示的还是bd用…

【浅水模型MATLAB】尝试复刻SCI论文中的溃坝流算例

【浅水模型MATLAB】尝试复刻SCI论文中的溃坝流算例 前言问题描述控制方程及数值方法浅水方程及其数值计算方法边界条件的实现 代码框架与关键代码模拟结果 更新于2024年9月17日 前言 这篇博客算是学习浅水方程&#xff0c;并利用MATLAB复刻Liang (2004)1中溃坝流算例的一个记录…