当前位置: 首页 > news >正文

C++系列之list的模拟实现

在这里插入图片描述

💗 💗 博客:小怡同学
💗 💗 个人简介:编程小萌新
💗 💗 如果博客对大家有用的话,请点赞关注再收藏 🌞

list的节点类

template
struct list_Node
{
public:
list_Node* _prev;
list_Node* _next;
T _val;
list_Node(const T& val = T())
{
_prev = _next = nullptr;
_val = val;
}
};`

list的迭代器类

//这里写入多个参数的目的是区分const迭代器
//传入不同的模板就会有不同的类
template<class T,class Ref ,class Ptr>
struct list_iterator
{public:typedef list_Node<T> Node;typedef list_iterator<T,Ref,Ptr> self;list_iterator(Node* node = nullptr){_node = node;}list_iterator(const self& i){_node(i._node);}//const对象不改变原数据T& operator*(){return _node->_val;}T* operator->(){return &_node->val;}self& operator++(){_node = _node->_next;return *this;}self operator++(int){self tmp(_node);_node = _node->_next;return tmp;}self& operator--(){_node = _node->_prev;return *this;}self& operator--(int){self tmp(_node);_node = _node->_prev;return tmp;}bool operator!=(const self& l){return _node != l._node;}bool operator==(const self& l){return _node == l._node;}Node* _node;};

构造函数

list(int n, const T& value = T())
{_head = new Node();_head->_prev = _head;_head->_next = _head;while (n--){push_back(value);}
}
template <class Intiterator>
list(Intiterator first, Intiterator last)
{//这三行代码的作用是制造一个头结点_head = new Node();_head->_prev = _head;_head->_next = _head;while (first != last){push_back(*first);first++;}
}
list(const list<T>& l)
{_head = new Node();_head->_prev = _head;_head->_next = _head;//这里制造一个list对象,构建与l对象一样的元素,在与*this进行调换。list<T> tmp (l.begin(),l.end());swap(tmp);
}	

析构函数

~list()
{clear();//复用clear()函数,如果元素是自定义类型,则一一析构,delete _head;_head = nullptr;
}

赋值运算符=

list<T>& operator=(const list<T> l)
{swap(l);return *this;
}

迭代器的使用


iterator begin()
{return iterator(_head->_next);
}
iterator end()
{return itertor(_head);
}
//const对象迭代器的使用返回的是const指针(实际上迭代器是一个模板,只是类型不同)
const_iterator begin()const
{return const_iterator(_head->_next);
}
const_iterator end()const
{return itertor(_head);
}		

list的元素大小和判空

size_t size()const//const与非const对象都可调用
{return _size;
}
bool empty()const
{return _size == 0;
}

访问list的头节点与尾节点

T& front()
{return _head->_next->_val;
}
const T& front()const
{return _head->_next->_val;
}
T& back()
{return _head->_prev->_val;
}
const T& back()const
{return _head->_prev->_val;
}

尾插,尾删,头插,尾删,插入,删除,交换,清空

//这里使用了函数的调用
void push_back(const T& val)
{insert(end(), val); 
}
void pop_back() 
{ erase(--end()); 
}
void push_front(const T& val) 
{ insert(begin(), val); 
}
void pop_front() 
{ erase(begin());
}
// 在pos位置前插入值为val的节点
//这里不会发生迭代器的失效,迭代器没有被改变,返回时返回pos之前的迭代器
iterator insert(iterator pos, const T& val)
{Node* newnode = new Node(val);Node* node_pos = pos.Node;Node* prev = node_pos->_prev;Node* next = node_pos->_next;prev->_next = next;next->_prev = prev;return newnode;
}
// 删除pos位置的节点,返回该节点的下一个位置
//这里发生迭代器的失效。指向pos指针变成野指针,返回时需要更新到该节点的下一个位置
iterator erase(iterator pos)
{Node* node_pos = pos.Node;Node* node_next = pos.Node->_next;node_pos->_prev->_next = node_pos->_next;node_next->_prev = node_pos->_prev;delete node_pos;return iterator(node_next);
}
//清除链表,只保留头节点
void clear()
{iterator it = begin();while (it != end()){erase(it);}_head->_prev = _head;_head->_next = _head;
}
//交换链表
void swap(const list<T>& L)
{Node* tmp = L._head;L._head = tmp;tmp = _head;
}
#include  <assert.h>
#include <iostream>
using namespace std;
namespace zjy
{template<class T>struct list_Node{public:list_Node* _prev;list_Node* _next;T _val;list_Node(const T& val = T()){_prev = _next = nullptr;_val = val;}};template<class T,class Ref ,class Ptr>struct list_iterator{public:typedef list_Node<T> Node;typedef list_iterator<T,Ref,Ptr> self;list_iterator(Node* node = nullptr){_node = node;}list_iterator(const self& i){_node(i._node);}T& operator*(){return _node->_val;}T* operator->(){return &_node->val;}self& operator++(){_node = _node->_next;return *this;}self operator++(int){self tmp(_node);_node = _node->_next;return tmp;}self& operator--(){_node = _node->_prev;return *this;}self& operator--(int){self tmp(_node);_node = _node->_prev;return tmp;}bool operator!=(const self& l){return _node != l._node;}bool operator==(const self& l){return _node == l._node;}Node* _node;};template<class T>class list{public:typedef list_Node<T> Node;typedef list_iterator<T,T&,T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;list(){_head = new Node();_head->_prev = _head;_head->_next = _head;}/*list(int n, const T& value = T()){_head = new Node();_head->_prev = _head;_head->_next = _head;while (n--){Node* newnode = new Node(value);Node* tail = _head->_prev;tail -> _next = newnode;newnode->_prev = _head;newnode->_next = _head;_head->_prev = newnode;tail = newnode;}}*/list(int n, const T& value = T()){_head = new Node();_head->_prev = _head;_head->_next = _head;while (n--){push_back(value);}}/*template <class Intiterator>list(Intiterator first, Intiterator last){_head = new Node();_head->_prev = _head;_head->_next = _head;Node* begin= first._node;Node* end = last._node;Node* tail = _head->_prev;while (begin != last){tail->_next = begin;begin->_prev = tail;begin->_next = _head;_head->_prev = begin;tail = begin;begin++;}}*/template <class Intiterator>list(Intiterator first, Intiterator last){_head = new Node();_head->_prev = _head;_head->_next = _head;while (first != last){push_back(*first);first++;}}void  swap(const list<T>& L){Node* tmp = L._head;L._head = tmp;tmp = _head;}list(const list<T>& l){_head = new Node();_head->_prev = _head;_head->_next = _head;list<T> tmp (l.begin(),l.end());swap(tmp);}list<T>& operator=(const list<T> l){swap(l);return *this;}~list(){clear();delete _head;_head = nullptr;}iterator begin(){return iterator(_head->_next);}iterator end(){return itertor(_head);}const_iterator begin()const{return const_iterator(_head->_next);}const_iterator end()const{return const_itertor(_head);}size_t size()const{return _size;}bool empty()const{return _size == 0;}T& front(){return _head->_next->_val;}const T& front()const{return _head->_next->_val;}T& back(){return _head->_prev->_val;}const T& back()const{return _head->_prev->_val;}void push_back(const T& val) {insert(end(), val); }void pop_back() { erase(--end()); }void push_front(const T& val) { insert(begin(), val); }void pop_front() { erase(begin()); }// 在pos位置前插入值为val的节点iterator insert(iterator pos, const T& val){Node* newnode = new Node(val);Node* node_pos = pos.Node;Node* prev = node_pos->_prev;Node* next = node_pos->_next;prev->_next = next;next->_prev = prev;return newnode;}// 删除pos位置的节点,返回该节点的下一个位置iterator erase(iterator pos){Node* node_pos = pos.Node;Node* node_next = pos.Node->_next;node_pos->_prev->_next = node_pos->_next;node_next->_prev = node_pos->_prev;delete node_pos;return iterator(node_next);}void clear(){iterator it = begin();while (it != end()){erase(it);}_head->_prev = _head;_head->_next = _head;}void test(){Node* tmp = _head->_next;while (tmp != _head){cout << tmp->_val << endl;tmp = tmp->_next;}}private:Node* _head;size_t _size;};
}

在这里插入图片描述

相关文章:

C++系列之list的模拟实现

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注再收藏 &#x1f31e; list的节点类 template struct list_Node { public: list_Node* _prev; list_…...

什么情况下你会使用AI工具(chatgpt、bard)?

在当今数字化和智能化的时代&#xff0c;AI工具已成为许多领域的常见工具。在本文中&#xff0c;我将探讨什么情况下会使用AI工具。前言 – 人工智能教程 ChatGPT是一款由OpenAI开发的大型语言模型&#xff0c;可以生成文本、翻译语言、编写不同类型的创意内容&#xff0c;并以…...

【go】两数求和

文章目录 题目代码解法2 代码仓库 题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案…...

软考高项-成本管理

工具和技术 三点估算 通过考虑估算中的不确定性与风险&#xff0c;使用3种估算值来界定活动成本的近似区间&#xff0c;可以提高活动成本估算的准确性&#xff1b; 储备分析 为应对成本的不确定性&#xff0c;成本估算中可以包括应急储备。应急储备的管理方法&#xff1a; 将…...

24年FRM备考知识点以及一级公式表

FRM一级公示表以及备考知识点 链接&#xff1a;https://pan.baidu.com/s/17RpFF9OyfRk7FGtEQrxf3A?pwd1234 提取码&#xff1a;1234 FRM二级公示表以及备考知识点 链接&#xff1a;https://pan.baidu.com/s/175D05wV1p94dIfBZThutCQ?pwd1234 提取码&#xff1a;1234...

Spring Cloud学习:二【详细】

目录 Nacos的配置 Nacos的单机启动 服务注册 Nacos服务分级存储模型 优先访问同集群的服务 根据权重负载均衡 环境隔离Namespace Nacos调用流程 Nacos与Eureka注册对比 Nacos与Eureka的共同点 Nacos与Eureka的区别 Nacos配置管理 统一配置 配置自动刷新 多环境配…...

Unity的live2dgalgame多语言可配置剧情框架

这段代码用于读取表格 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using OfficeOpenXml; using System.IO; using UnityEngine.Networking; using UnityEngine.UI; using Random UnityEngine.Random;public class Plots…...

再畅通工程(最小生成树)

题目描述&#xff1a;还是畅通工程 某省调查乡村交通状况&#xff0c;得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通&#xff08;但不一定有直接的公路相连&#xff0c;只要能间接通过公路可达即可&#xff09;&…...

前后端分离不可忽视的陷阱,深入剖析挑战,分享解决方案,助你顺利实施分离开发。

不管你设计的系统架构是怎么样&#xff0c;最后都是你的组织内的沟通结构胜出。这个观点一直在组织内不断地被证明&#xff0c;但也不断地被忽略。 前后端分离的利与弊 近几年&#xff0c;随着微服务架构风格的引入、前后端生态的快速发展、多端产品化的出现&#xff0c;前后…...

(四)库存超卖案例实战——优化redis分布式锁

前言 在上一节内容中&#xff0c;我们已经实现了使用redis分布式锁解决商品“超卖”的问题&#xff0c;本节内容是对redis分布式锁的优化。在上一节的redis分布式锁中&#xff0c;我们的锁有俩个可以优化的问题。第一&#xff0c;锁需要实现可重入&#xff0c;同一个线程不用重…...

【ROS入门】雷达、摄像头及kinect信息仿真以及显示

文章结构 雷达信息仿真以及显示Gazebo仿真雷达配置雷达传感器信息xacro文件集成启动仿真环境 Rviz显示雷达数据 摄像头信息仿真以及显示Gazebo仿真摄像头新建xacro文件&#xff0c;配置摄像头传感器信息xacro文件集成启动仿真环境 Rviz显示摄像头数据 kinect信息仿真以及显示Ga…...

实用篇-认识微服务

一、服务架构演变 1. 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署 单体架构的优点&#xff1a; 架构简单部署成本低 单体架构的缺点&#xff1a; 耦合度高 2. 分布式架构 分布式架构&#xff1a; 根据业务功能对系…...

【产品运营】产品需求应该如何管理

产品项目在进行时经常会有一些需求需要实现&#xff0c;需求是产品更新迭代的动力&#xff0c;需求也是从用户诉求转化而来&#xff1b;在做需求管理时&#xff0c;我们需要判断一个需求的优先级等方面&#xff0c;对产品进行优化&#xff1b; 目录&#xff1a; 一、 为什么要…...

Linux 系统调用IO口,利用光标偏移实现文件复制

用系统调用IO函数实现从一个文件读取最后2KB数据并复制到另一个文件中&#xff0c;源文件以只读方式打开&#xff0c;目标文件以只写的方式打开&#xff0c;若目标文件不存在&#xff0c;可以创建并设置初始值为0664&#xff0c;写出相应代码&#xff0c;要对出错情况有一定的处…...

【原创】指针变量作为函数参数要点注意

指针变量作为函数参数要点注意&#xff08;已写至笔记&#xff09; 1传参指针不加*&#xff08;main中函数&#xff09; 2收参指针要加*&#xff08;被main调用的函数&#xff09; 3传参指针名可与收参指针名不同&#xff0c;不影响 4【问】如何看主函数中指针所指内容是否改变…...

SpringMVC Day 04 : 数据绑定

前言 SpringMVC是一个非常流行的Java Web框架&#xff0c;它提供了很多方便的功能和工具来帮助我们构建高效、灵活的Web应用程序。其中&#xff0c;数据绑定就是SpringMVC中非常重要的一部分&#xff0c;它可以帮助我们方便地将请求参数绑定到Java对象上&#xff0c;从而简化了…...

2.3.1 协程设计原理与汇编实现

1.为什么要有协程&#xff1f; 同步的编程方式&#xff0c;异步的性能。同步编程时&#xff0c;我们需要等待io就绪。但是在协程这里&#xff0c;我们使用一种机制&#xff0c;当io需要等待时&#xff0c;就切到下一个io&#xff0c;之后当之前的io就绪时&#xff0c;再切换回来…...

J2EE项目部署与发布(Windows版本)->会议OA单体项目Windows部署,spa前后端分离项目Windows部署

会议OA单体项目Windows部署spa前后端分离项目Windows部署 1.会议OA单体项目Windows部署&#xff08;以实施的角度&#xff09; 将项目放入webapp&#xff0c;项目能够访问: 首先拿到war包和数据库脚本&#xff0c;并检查是否有什么问题。 如何查看项目报错信息&#xff08;当你…...

Lua脚本语言

1. 概念 Lua&#xff08;发音为"loo-ah"&#xff0c;葡萄牙语中的"lua"意为月亮&#xff09;是一种轻量级的、高效的、可嵌入的脚本编程语言。官网Lua最初由巴西计算机科学家Roberto Ierusalimschy、Waldemar Celes和Luiz Henrique de Figueiredo于1993年开…...

cat()函数和print()函数的区别

目录 区别一&#xff1a; 区别二&#xff1a; cat、print函数都是输出函数。 区别一&#xff1a; cat()函数不能赋值&#xff1b; print()函数可以赋值。 x<-cat("hello world") //赋值 hello world x //cat函数无返回值 NULLy<-print("hello …...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...