【C++教程从0到1入门编程】第十三篇:STL中list类的模拟实现

一、list的模拟实现

#include<iostream>
#include<assert.h>
#pragma once
namespace jyr
{template<class T>struct _list_node{_list_node<T>* _next;_list_node<T>* _prev;T _data;_list_node(const T& val = T()):_next(nullptr), _prev(nullptr), _data(val){}};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):_node(node){}//*it,返回_dataRef operator*(){return _node->_data;}//it->datePtr operator->(){return &_node->_data;}//it++,返回还是一个迭代器,前置加加Self& operator++(){_node = _node->_next;return *this;}//前置--Self& operator--(){_node = _node->_prev;return *this;}//后置加加Self operator++(int){Self tmp(*this);  //创建临时变量返回,后置加加,加加之前不变//_list_iterator<T>tmp = *this;_node = _node->_next;//++(*this)return tmp;}//后置减减Self operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}//==bool operator ==(const Self& it){return _node = it._node;}//it!=end()bool operator!=(const Self& it){return _node != it._node;}};template<class T>class list{public:typedef _list_node<T> Node;public:typedef _list_iterator<T,T&,T*> iterator;typedef _list_iterator<T,const T&,const T*> const_iterator;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);}//带头双向循环链表list()                      //list的构造{_head = new Node;_head->_next = _head;_head->_prev = _head;} //l2(l1)list(const list<T>& l1)            //拷贝构造{//链表的最初状态_head = new Node;_head->_next = _head;_head->_prev = _head;//const_iterator it = l1.begin();   //构造一个const迭代器尾插到新的迭代器中//while (it != l1.end())//{//	this->push_back(*it);//	it++;//}for (auto e : l1){push_back(e);}}list<T>& operator=(const list<T>& l1){if (this != &l1){clear();for (auto e : l1){push_back(e);}}return *this;}//现代版的拷贝构造//list<T>& operator=(list<T> l1)//{//	swap(_head, l1._head);//	return *this;//}void clear(){iterator it = begin();while (it != end()){erase(it++);         //erase要自己单独实现出来}}~list()                      //析构函数{clear();                 //clear没有删除头结点delete _head;_head = nullptr;}size_t size()  const{}bool empty() const{return _head->_next == _head->_prev;}//T x  如果T类型是vector或者是string就造成了深拷贝,那么就得传引用,传引用不改变x就加constvoid push_back(const T& x)  {//Node* tail = _head->_prev;//Node* newnode = new Node(x);//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void insert(iterator pos, const T& x)    //在pos这个迭代器的前面插入一个节点{Node* newnode = new Node(x);//pos 是个迭代器,而迭代器又是节点的指针,所以可以通过迭代器找到这个节点Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;//return iterator(newnode);}void pop_back(){erase(--end());}void pop_front(){erase(begin());//end是最后一个有效数据的下一个位置,所以end先减减,删除end减减的位置}void erase(iterator pos){//pos是一个迭代器,节点的指针,可以找到这个节点//找到要删除的节点delassert(pos != end());//头结点不能删除Node* del = pos._node;Node* next = del->_next;//假设有1 2 3节点,要删除pos位置2节点,//先2节点的前一个节点1节点的下一个节点指向2指向的3节点//然后要把3和1链接起来,把3的前一个节点指向1,//2的下一个节点3节点的前一个节点指向2的前一个节点//删除2del->_prev->_next = del->_next; del->_next->_prev = del->_prev;delete del;//return iterator(next);//返回节点的下一个位置}private:Node* _head;};void testlist1(){list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(10);lt1.push_back(20);lt1.pop_back();list<int>::iterator it = lt1.begin();while (it != lt1.end()){std::cout << *it << " ";++it;}std::cout << std::endl;}struct Date{int _year = 0;int _month = 1;int _day = 1;};void print_list(const list<int>& lt1){list<int>::const_iterator it = lt1.begin();while (it != lt1.end()){std::cout << *it << " ";it++;}std::cout << std::endl;}void testlist2(){list<Date> lt1;lt1.push_back(Date());lt1.push_back(Date());list<Date>::iterator it = lt1.begin();while (it != lt1.end()){/*std::cout << *it << " ";*///it->Date->_year  std::cout << it->_year << ":" << it->_month << ":" << it->_day << std::endl;std::cout << (*it)._year << ":" << (*it)._month << ":" << (*it)._day << std::endl;++it;}//print_list(lt1);}void testlist3(){list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);list<int>l2(l1); //拷贝构造,用l1拷贝构造l2for (auto e : l1){std::cout << e << " ";}std::cout << std::endl;for (auto e : l2){std::cout << e << " ";}std::cout << std::endl;}
}

二、list与vector之间的对比

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

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

相关文章

Zabbix 配置使用

目录 配置流程 添加组机组 添加模板 添加主机 配置图形 配置大屏 Monitoring 配置地图 最新数据 故障 使用IT服务 使用报表 资产管理 全局搜索 导入导出 用户权限 用户组权限 用户 匿名用户 调试模式 与 LDAP 对接 维护模式 故障确认 批量更新 配置流程…

【办公类-21-10】三级育婴师 视频转文字docx(等线小五单倍行距),批量改成“宋体小四、1.5倍行距、蓝色字体、去掉五分钟”

作品展示 背景需求 今天将最后3个育婴师操作视频做整理 第1步&#xff1a;视频MP4转MP3 【办公类-40-01】20240311 用Python将MP4转MP3提取音频 &#xff08;家长会系列一&#xff09;-CSDN博客文章浏览阅读393次&#xff0c;点赞9次&#xff0c;收藏6次。【办公类-40-01】20…

[项目前置]websocket协议

websocket协议介绍 WebSocket 协议是一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得客户端和服务器之间的数据交换变得更简单&#xff0c;允许服务器主动向客户端推送数据。它在 2011 年成为国际标准&#xff0c;现在被所有现代浏览器支持。WebSocket 设计用于…

iNet Network Scanner Mac 网络扫描工具

iNet Network Scanner for Mac是一款功能强大的网络扫描工具&#xff0c;专为Mac用户设计。它提供了全面而深入的网络分析功能&#xff0c;使用户能够轻松获取Mac连接的网络和设备的详细信息。 软件下载&#xff1a;iNet Network Scanner Mac v3.1.0激活版 这款软件具备多种扫描…

业务服务:xss攻击

文章目录 前言一、使用注解预防1. 添加依赖2. 自定义注解3. 自定义校验逻辑4. 使用 二、使用过滤器1. 添加配置2. 创建配置类3. 创建过滤器4. 创建过滤器类5. 使用 前言 xss攻击时安全领域中非常常见的一种方法&#xff0c;保证我们的系统安全是非常重要的 xss攻击简单来说就…

TCP(socket 套接字)编程 1

一、TCP套接字编程架构如下 二、相关代码实现 1、服务器端代码 package com.company;import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket;public class Main {public static void main(String[] args) {…

javaWeb健身房管理系统

一、简介 随着人们健康意识的增强和生活水平的提高&#xff0c;健身已经成为了现代人生活中不可或缺的一部分。为了更好地管理健身房的日常运营&#xff0c;我们设计并开发了一款基于 JavaWeb 的健身房管理系统。本系统采用了最新的技术&#xff0c;包括 Spring Boot、MyBatis…

nacos集群搭建实战

集群结构图 初始化数据库 Nacos默认数据存储在内嵌数据库Derby中&#xff0c;不属于生产可用的数据库。官方推荐的使用mysql数据库&#xff0c;推荐使用数据库集群或者高可用数据库。 首先新建一个数据库&#xff0c;命名为nacos&#xff0c;而后导入下面的SQL&#xff08;直…

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示(PC端、手机端、平板端)

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示&#xff08;PC端、手机端、平板端&#xff09; 智慧工地系统多端展示&#xff08;PC端、手机端、平板端&#xff09;;数字孪生可视化大屏&#xff0c;一张图掌握项目整体情况;使用轻量化模型&#xff0c;部署三…

ubuntu22.04配置Azure Kinect DK深度相机

一.安装SDK 今天我来配置一下微软公司的Azure Kinect DK深度相机,以前在ubuntu18.04上配置过,因为官方说唯一支持linux版本是18.04,所以在18.04中配置还算顺利 but这不代表不可以在更高版本的ubuntu中使用,只不过需要自己去多配置一些东西 apt 源安装 更新源: c…

25.7 MySQL 数据库和表的基本操作

1. 基础知识 1.1 一条数据的存储过程 存储数据确实是处理数据的基石, 只有确保数据被准确无误且有条理地存储, 我们才能对其进行深入的处理和细致的分析. 否则, 这些数据就像是一团毫无章法的乱麻, 让我们难以捉摸其内在的逻辑和价值.那么, 如何才能够将用户那些与经营紧密相关…

VITIS更新硬件平台

VITIS硬件平台更新以后如何重新导入 在之前建立的硬件平台上右击&#xff0c;选择Update Hardware Specification&#xff0c;选择最新导出的硬件平台文件&#xff1b; 重建板级支持包 选择复位重建BSP源文件&#xff0c;俩个地方的BSP都Reset一下&#xff0c;然后Build&…

Transformer的前世今生 day08(Positional Encoding)

前情提要 Attention的优点&#xff1a;解决了长序列依赖问题&#xff0c;可以并行。Attention的缺点&#xff1a;开销变大了&#xff0c;而且不存在位置关系为了解决Attention中不存在位置关系的缺点&#xff0c;我们通过位置编码的形式加上位置关系 Positional Encoding&…

LinkedIn账号为什么被封?被封后如何解决?

近期会有一些小伙伴说自己遇到了帐号无法登录的情况&#xff0c;其实出现领英帐号被封号(被限制登录)主要会有两类情况&#xff0c;今天就给大家分享一下如果被封该如何解决&#xff0c;强烈建议收藏。 在电脑领英官网或者手机领英APP上&#xff0c;输入领英帐号密码点击登录后…

HCIP的学习(4)

GRE和MGRE VPN---虚拟专用网络。指依靠ISP&#xff08;运营商&#xff09;或其他公有网络基础设施上构建的专用的安全数据通信网络。该网络是属于逻辑上的。​ 核心机制—隧道机制&#xff08;封装技术&#xff09; GRE—通用路由封装 ​ 三层隧道技术&#xff0c;并且是属于…

代码随想录 图论

目录 797.所有可能得路径 200.岛屿数量 695.岛屿的最大面积 1020.飞地的数量 130.被围绕的区域 417.太平洋大西洋水流问题 827.最大人工岛 127.单词接龙 841.钥匙和房间 463.岛屿的周长 797.所有可能得路径 797. 所有可能的路径 中等 给你一个有 n 个节点的…

什么是V R美术馆|V R互动体验店加盟|虚拟现实元宇宙

VR美术馆是利用虚拟现实&#xff08;VR&#xff09;技术构建的数字化美术馆&#xff0c;通过虚拟展厅和虚拟展览等形式展示艺术作品、举办艺术展览&#xff0c;为用户提供一种沉浸式的艺术体验。用户可以通过穿戴VR头显等设备&#xff0c;在虚拟环境中自由浏览各种艺术作品&…

20240319-1-过拟合与欠拟合

过拟合欠拟合面试题 1. 如何理解高方差与低偏差? 模型的预测误差可以分解为三个部分: 偏差(bias)&#xff0c; 方差(variance) 和噪声(noise). 偏差 偏差度量了模型的期望预测与真实结果的偏离程度&#xff0c; 即刻画了学习算法本身的拟合能力。偏差则表现为在特定分布上…

启动Hbase shell时有许多日志信息的解决办法

一、问题描述 在使用HBase时&#xff0c;当我们启动HBase shell时&#xff0c;会显示大量的日志信息&#xff0c;这些日志信息可能会干扰我们的操作&#xff0c;我们希望在启动HBase shell时不显示这些日志信息。 二、解决方案 方案一:修改配置文件 我们可以通过修改HBase的…

数据采集用,集成了主流工业通讯协议

IoTClient 是一个物联网设备通讯协议实现客户端&#xff0c;集成了主流工业通讯协议&#xff0c;包括主流PLC通信读取、ModBus协议、Bacnet协议等。该组件基于.NET Standard 2.0&#xff0c;适用于.NET的跨平台开发&#xff0c;可在Windows、Linux等系统上运行&#xff0c;甚至…