list 的实现

在这里插入图片描述
上图的下述代码实现:

void push_back(const T& x)
{Node* newnode = new Node(x);Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;
}

顺序表可以用原生指针代替迭代器的指针,但链表不可以,链表的指针++并不能够保证找到下一个节点的位置。因此需要把当前节点封装起来作为迭代器,在迭代器类中重载++函数,使其++也可以找到下一个结点的位置。

下述代码为list的迭代器代码,对于拷贝构造使用浅拷贝就可以,因为只需要让另一个指针指向当前节点的资源,而链表不可以浅拷贝。对于析构函数,迭代器不能去析构资源。因为资源是在链表中的,迭代器只是访问。

对于迭代器而言,需要完成 *it,重载 ++ 和 – 函数,还有迭代器的比较节点是否相等函数。
在这里插入图片描述

const迭代器为什么是const_iterator而不是const iterator?
const迭代器是迭代器指向的内容不能修改而不是迭代器本身不能修改,而const iterator是iterator不能修改,因此不满足需求。
const迭代器相当于要模拟的不是 T* const 而是 const T*
在list中写了一个模板类,编译器底层生成了两个类。
在这里插入图片描述

const类型的迭代器只有operator*和operator->的返回值和普通迭代器的返回值不同,返回值不同就可以用模板。
对于下述代码自定义类型A而言,如果想用迭代器->读取A的内容,就需要在迭代器中重载->,也就是定义的模板 Ptr 函数。

template <class T , class Ref, class Ptr>
struct ListIterator
{typedef ListNode<T> Node; typedef ListIterator<T, Ref, Ptr> Self;Node* _node; //内置类型浅拷贝就可以了ListIterator(Node* node):_node(node){}//*it 可读可写,得引用返回。//T& operator*()Ref operator*(){return _node->_data;}// it->//T* operator->()Ptr operator->(){//node里的data进行取地址,返回一个T类型的指针指向data的地址,//如果存放的是A类型数据,data就是一个A类型指针就可以访问a1和a2return &_node->_data; }Self& operator++() //前置++ 返回++以后的值{_node = _node->_next;return *this;}Self operator++(int){//让tmp指针指向NOde*的资源就行了 浅拷贝够用。Self tmp(*this); _node = _node->_next;return tmp;}Self& operator--() //前置-- 返回--以后的值{_node = _node->_prev;return *this;}Self operator--(int){//让tmp指针指向NOde*的资源就行了 浅拷贝够用。Self tmp(*this);_node = _node->_prev;return tmp;}bool operator!=(const Self& it){return _node != it._node;}bool operator==(const Self& it){return _node == it._node;}
};

只有list才知道链表的开始和结束,因此得用list把封装的iterator连接起来。
完整的list代码:

namespace ggg
{// 节点类型定义template<class T>struct ListNode //节点的数据需要公开 用struct{ListNode<T>* _next;ListNode<T>* _prev;T _data;ListNode(const T& x = T()):_next(nullptr), _prev(nullptr), _data(x){}};// 封装节点迭代器完成的工作 普通迭代器和const迭代器使用模板复用template <class T , class Ref, class Ptr>struct ListIterator{typedef ListNode<T> Node; typedef ListIterator<T, Ref, Ptr> Self;Node* _node; //内置类型浅拷贝就可以了ListIterator(Node* node):_node(node){}//*it 可读可写,得引用返回。//T& operator*()Ref operator*(){return _node->_data;}// it->//T* operator->()Ptr operator->(){//node里的data进行取地址,返回一个T类型的指针指向data的地址,//如果存放的是A类型数据,data就是一个A类型指针就可以访问a1和a2return &_node->_data; }Self& operator++() //前置++ 返回++以后的值{_node = _node->_next;return *this;}Self operator++(int){//让tmp指针指向NOde*的资源就行了 浅拷贝够用。Self tmp(*this); _node = _node->_next;return tmp;}Self& operator--() //前置-- 返回--以后的值{_node = _node->_prev;return *this;}Self operator--(int){//让tmp指针指向NOde*的资源就行了 浅拷贝够用。Self tmp(*this);_node = _node->_prev;return tmp;}bool operator!=(const Self& it){return _node != it._node;}bool operator==(const Self& it){return _node == it._node;}};/// 链表的类template<class T>class list{typedef ListNode<T> Node;public://typedef ListIterator<T> iterator;//typedef ListConstIterator<T> const_iterator;typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;iterator begin(){//return iterator(_head->_next); 匿名对象iterator it(_head->_next);return it;}//链表的结尾是最后一个节点的下一个位置,也就是哨兵位iterator end() {return iterator(_head);}//类比:相当于要模拟的不是 T* const 而是 const T*const_iterator begin() const{const_iterator it(_head->_next);return it;}const_iterator end() const{return const_iterator(_head);}///void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}void clear(){iterator it = begin();while (it != end()) // !=end() 就不会清除掉head节点{it = erase(it);}}list() //构造{empty_init();}//lt1(lt)list(const list<T>& lt) //拷贝构造{empty_init();for (auto& e : lt){push_back(e);}}list<T>& operator=(list<T> lt) //赋值{std::swap(_head, lt._head);std::swap(_size, lt._size);return *this;}~list() //析构{clear();delete _head;_head = nullptr;}void push_back(const T& x) //插入{//Node* newnode = new Node(x);//Node* tail = _head->_prev;//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;insert(end(), x); //在end前面插入就是尾插}void push_front(const T& x){insert(begin(), x);}//尾删,删掉end()(哨兵位head)的下一个,也就是最后一个有数据的位置,--就是求上一个位置prevvoid pop_back() {erase(--end());}void pop_front() //头删,begin()就是头{erase(begin());}void insert(iterator pos, const T& val){Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;}iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;_size--;return iterator(next);}size_t size() const{return _size;}bool empty(){return _size == 0;}private:Node* _head;size_t _size;};/struct A{int _a1;int _a2;A(int a1 = 0, int a2 = 0):_a1(a1),_a2(a2){}};}

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

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

相关文章

STM32 第3章 如何用串口下载程序

时间:2024.10.28 一、学习内容 1、安装USB转串口驱动 1.1串口下载连接示意图 1、USB转串口模块在开发板上是一个独立的模块,可通过调帽与其他串口连接,USART1/2/3/4/5 2、只有USART1才具有串口下载的功能。 3、CH340是电平转换芯片,将电脑端输出的USB电平和单片机输…

探索PDFMiner:Python中的PDF解析利器

文章目录 探索PDFMiner&#xff1a;Python中的PDF解析利器1. 背景介绍&#xff1a;为何选择PDFMiner&#xff1f;2. PDFMiner是什么&#xff1f;3. 如何安装PDFMiner&#xff1f;4. 简单库函数使用方法4.1 提取文本4.2 获取页面布局信息4.3 提取表格数据4.4 提取图像 5. 应用场…

Spring Boot驱动的植物健康监测革命

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理植物健康系统的相关信息成为必然。开发合适…

植物病害图像分割系统:分割算法优化

植物病害图像分割系统源码&#xff06;数据集分享 [yolov8-seg-EfficientHead&#xff06;yolov8-seg-EfficientRepBiPAN等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源A…

vue使用高德地图实现轨迹显隐

<template><div><el-button type"primary" click"pathShowOrHide">轨迹显/隐</el-button><div id"container" /></div> </template><script> import AMapLoader from amap/amap-jsapi-loaderex…

基于Spring Boot的在线摄影工作室开发指南

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理网上摄影工作室的相关信息成为必然。开发合…

法国第二大互联网服务商遭遇数据泄露,波及1900万用户

据BleepingComputer消息&#xff0c;法国主要互联网服务提供商 &#xff08;ISP&#xff09; Free 在上周末证实&#xff0c;稍早前有黑客入侵了其系统并窃取了用户的个人信息。 Free是法国第二大电信公司&#xff0c;也是欧洲第六大移动运营商 Iliad Group 的子公司&#xff0…

python道格拉斯算法的实现

废话不多说 直接开干 需要用到模块 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple math #对浮点数的数学运算函数 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple shapely #提供几何形状的操作和分析&#xff0c;如交集、并集、差集等 pip install -i …

Lucas带你手撕机器学习——岭回归

岭回归&#xff08;Ridge Regression&#xff09; 一、背景与引入 在进行线性回归分析时&#xff0c;我们常常面临多重共线性的问题。多重共线性指的是自变量之间高度相关&#xff0c;这会导致回归系数的不稳定性&#xff0c;使得模型的预测能力降低。传统的线性回归通过最小…

MacOS下载安装Logisim(图文教程)

本章教程主要介绍如何在MacOS系统中安装Logisim。 一、Logisim是什么? Logisim是一个用于电子逻辑门电路模拟的教育工具软件。它允许用户通过图形界面构建和测试复杂的数字逻辑电路,如加法器、解码器、编码器、寄存器、内存等,从而帮助学生理解计算机硬件的工作原理。 二、如…

Nature Communications|一种3D打印和激光诱导协同策略用于定制功能化器件(3D打印/激光直写/柔性电子/人机交互/柔性电路)

美国密苏里大学机械与航天工程系Jian Lin团队,在《Nature Communications》上发布了一篇题为“Programmed multimaterial assembly by synergized 3D printing and freeform laser induction”的论文。论文内容如下: 一、 摘要 在自然界中,结构和功能材料经常形成程序化的三…

UE5 第一人称示例代码阅读0 UEnhancedInputComponent

UEnhancedInputComponent使用流程 我的总结示例分析firstthenand thenfinally&代码关于键盘输入XYZ 我的总结 这个东西是一个对输入进行控制的系统&#xff0c;看了一下第一人称例子里&#xff0c;算是看明白了&#xff0c;但是感觉这东西使用起来有点绕&#xff0c;特此梳…

修复卡密商品每次保存的时候库存都会减少的问题

5.0版本中&#xff0c;卡密商品每次保存的时候&#xff0c;库存都会减少的问题 修改文件crmeb/app/services/product/sku/StoreProductAttrServices.php 删除或者注释箭头所指的哪一行代码 增加红框内的代码&#xff0c;重新保存商品库存正常 必须复制下方代码&#xff0c;才…

Bug | 项目中数据库查询问题

问题描述 理论上&#xff0c;点击查询后&#xff0c;表头应当显示中文。而不是上面的在数据库中的表头【如上图示】 正常点击查询后&#xff0c;如果没有输入值&#xff0c;应当是查询所有的信息。 原因分析&#xff1a; 这里是直接使用SELECT * 导致的。例如&#xff1a; S…

RagFlow本地部署使用

文章目录 前言一、RAGFlow的安装和部署1.安装2.注册登录 二、添加模型1.配置 Ollama 连接大模型2.配置Xinference连接大模型 三、知识库使用1.创建知识库2.上传文件解析 四、聊天 前言 开源RAGFlow引擎&#xff1a;打造无幻觉、高精度的文档理解与生成体验 RAGflow&#xff0…

云对象存储进阶

《使用Minio搭建文件服务器》一文对minio作了简单的介绍&#xff0c;本文为进阶学习。 1.对象存储产品介绍 目前市场上流行各种对象存储服务&#xff0c;诸如以下&#xff1a; Amazon S3&#xff1a;亚马逊提供的服务&#xff0c; 是市场上最成熟的产品&#xff0c;拥有最大的…

106. 平行光阴影计算

点光源PointLight、聚光源SpotLight、平行光DirectionalLight等都可以产生阴影&#xff0c;就像实际生活中的影子。 环境光AmbientLight这种没有方向的光源&#xff0c;不会产生阴影。 本节课给大家讲解平行光DirectionalLight的阴影效果如何实现。 平行光DirectionalLight阴…

【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python电话号码 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python电话号码 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…

机器学习之数据预处理

一.标准化 二.归一化 三.二值化 四.独热编码与标签编码 一.标准化 1.什么是标准化&#xff1f; 标准化指的是将数据按比例缩放&#xff0c;使之落入一个小的特定区间。在大多数情况下&#xff0c;这个区间是[0, 1]&#xff0c;但有时也可以是[-1, 1]。标准化后的数据的平均值…