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

C++ list链表模拟实现

目录

前言:

模拟实现:

迭代器的实现:

list类功能函数实现:

 初始化成空函数(empty_init):

构造函数:

 拷贝构造函数:

尾插(push_back):

插入(insert):

删除(erase):

 尾删(pop_back):

头插(push_front):

头删(pop_front):

 清理(clear):

 交换(swap):

赋值重载:

析构:

代码


前言:

  在学习完list的基本功能后,我自己模拟实现了一个list,具备一些常用的基本功能,这篇博客用来分享并记录,方便后续复习。

模拟实现:

因为list中可以存很多种类型,比如int,char,float,等,还可能是自定义类型,所以我打算使用类模板,先把简单的节点弄成类模板:

接下来就是list的类模板:

迭代器的实现:

  这里迭代器的模拟实现不能像vector一样简单的使用原生指针,因为链表的地址不是连续的,我们在进行原生指针的++或者--操作时,是无法实现访问下一个或者上一个元素的,那该怎样实现简单的对迭代器++或者--就能实现访问下一个或者上一个元素呢?

  这里有一个巧妙地方法就是借助类,没错,我们将原生指针放入一个名为Listiterator的类里面,然后在这个类中,使用运算符重载,重载++,--,*,->等运算符,就能像库里面一样使用迭代器了。

 上图的Ref和Ptr模板分别是传引用和传指针,用于应对const 迭代器的使用 ,保证const迭代器可以修改迭代器,但不能修改该迭代器指向的内容。接下来开始在这个类中重载各种运算符:

这几个运算符重载都很简单,应该都能看懂,接下来进入list类模板中,就行list的功能函数实现:

list类功能函数实现:

先来几个简单但又很重要的函数实现:

 初始化成空函数(empty_init):

构造函数:

有了上面这个函数后,构造函数就简单了,直接复用即可:

 拷贝构造函数:

尾插(push_back):

插入(insert):

删除(erase):

 尾删(pop_back):

头插(push_front):

头删(pop_front):

 清理(clear):

 交换(swap):

赋值重载:

 此处传值传参的妙处:

list1=iist2,进入函数此时lt是list2的拷贝,因为swap是成员函数,所以有一个隐含的this指针,此时只需传参lt就可以完成lt和list1交换,间接完成对list1的赋值,同时没有改变list2,只是改变了lt,而lt出作用域后就会消失。

析构:

代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
namespace sxk
{   template<class T>struct ListNode{ListNode<T>* next;//下一个节点的地址ListNode<T>* prev;//上一个节点的地址T val;//数据ListNode(const T& x = T())//节点的构造函数:next(nullptr), prev(nullptr), val(x){}};template<class T,class Ref,class Ptr>struct Listiterator{typedef ListNode<T> Node;typedef Listiterator<T, Ref, Ptr> Self;typedef Listiterator<T, T&, T*> iterator;typedef Listiterator<T, const T&, const T*> const_iterator;Node* _node;Listiterator(Node* node)//迭代器的构造函数:_node(node){}Ref operator*(){return _node->val;}Ptr operator->(){return &_node->val;}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;}bool operator==(const Self& it){return _node == it._node;}bool operator!=(const Self& it){return _node != it._node;}};template<class T>class list{public:typedef ListNode<T> Node;typedef Listiterator<T, T&, T*> iterator;typedef Listiterator<T, const T&, const T*> const_iterator;iterator begin(){return _head->next;}iterator end(){return _head;}const_iterator begin()const{return _head->next;}const_iterator end()const{return _head;}size_t size(){return _size;}bool empty(){return _size == 0;}void empty_init(){_head = new Node;//new出头节点_head->next = _head;//头节点下一个指向自己_head->prev = _head;//头节点上一个指向自己_size = 0;}list()//构造函数{empty_init();}list(const list<T>& lt)//拷贝构造函数{empty_init();//先初始化成只有一个头节点for (auto& x : lt){push_back(x);//直接尾插即可}}list<T>& operator=(const list<T> lt)//lt是赋值类的拷贝{swap(lt);//交换lt和this,可以完成赋值并不影响赋值类return *this;}void swap(const list<T>& lt){std::swap(_head, lt._head);//直接调用库里的swap交换两个成员变量即可std::swap(_size, lt._size);}void clear(){iterator it = begin();while (it != end())//遍历删除{it = erase(it);//更新it,防止erase后迭代器失效it++;}}~list(){clear();//先清理,只保留一个头节点delete _head;//释放头节点_head = nullptr;}void push_back(const T& x){Node* newnode = new Node;//new出新节点newnode->val = x;//给新节点赋值Node* tail = _head->prev;//记录尾节点tail->next = newnode;//尾节点的下一个指向新节点newnode->next = _head;//新节点的next指向头节点newnode->prev = tail;//新节点的prev指向之前旧的尾节点_head->prev = newnode;//头节点的prev指向新节点_size++;}void push_front(){insert(begin());}void pop_back(){erase(--end());//直接复用erase,注意end指向的是头节点,所以要--}void pop_front(){erase(begin());}void insert(iterator pos, const T& x)//在pos位置前插入x{Node* newnode = new Node;//new出新节点newnode->val = x;//给新节点赋值Node* cur = pos._node;//记录当前pos位置Node* prev = cur->prev;//记录pos前一个prev->next = newnode;//pos前一个节点的next指向新节点newnode->next = cur;//新节点的next指向pos节点newnode->prev = prev;//新节点的prev指向pos前一个节点cur->prev = newnode;//pos的prev指向新节点_size++;}iterator erase(iterator pos)//删除pos位置的值{Node* cur = pos._node;//记录pos位置的节点Node* prev = cur->prev;//记录pos的前一个节点Node* next = cur->next;//记录pos的下一个节点prev->next = cur->next;//pos的前一个节点的next指向pos的下一个节点next->prev = prev;//pos的下一个节点的prev指向pos的前一个节点delete cur;//释放pos位置的节点cur = nullptr;//置为空_size--;return iterator(next);//防止erase后迭代器失效,更新迭代器}private:Node* _head;size_t _size;};void Print_List(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){cout << (*it) << " ";it++;}cout << endl;}
}

相关文章:

C++ list链表模拟实现

目录 前言&#xff1a; 模拟实现&#xff1a; 迭代器的实现&#xff1a; list类功能函数实现&#xff1a; 初始化成空函数&#xff08;empty_init&#xff09;&#xff1a; 构造函数&#xff1a; 拷贝构造函数&#xff1a; 尾插&#xff08;push_back&#xff09;: 插入…...

LangChain - PromptTemplate

文章目录 关于 Prompt关于 PromptTemplate基本创建无变量输入1个变量多变量使用 from_template 自动推断 input_variables 聊天模板使用 from_template 方法构建使用 PromptTemplate 构建 MessagePromptTemplate使用一或多个 MessagePromptTemplates 构建一个 ChatPromptTempla…...

spring cloud gateway openfeign 联合使用产生死锁问题

spring cloud gateway openfeign 联合使用产生死锁问题&#xff0c;应用启动的时候阻塞卡住。 spring.cloud 版本如下 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><vers…...

【WPF应用37】WPF基本控件-DatePicker的详解与示例

WPF&#xff08;Windows Presentation Foundation&#xff09;是微软推出的一个用于构建桌面应用程序的图形子系统。在WPF中&#xff0c;DatePicker控件是一个常用的控件&#xff0c;用于用户选择日期。DatePicker控件提供了一个简洁直观的界面&#xff0c;使用户能够轻松选择日…...

GitHub教程:最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程)

&#x1f42f; GitHub教程&#xff1a;最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程) &#x1f4c1; 文章目录 &#x1f42f; GitHub教程&#xff1a;最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图…...

编译Nginx配置QUIC/HTTP3.0

1. 安装BoringSSL sudo apt update sudo apt install -y build-essential ca-certificates zlib1g-dev libpcre3 \ libpcre3-dev tar unzip libssl-dev wget curl git cmake ninja-build mercurial \ libunwind-dev pkg-configgit clone --depth1 https://github.com/google/b…...

【JavaWeb】Day38.MySQL概述——数据库设计-DQL

数据库设计——DQL 介绍 DQL英文全称是Data Query Language(数据查询语言)&#xff0c;用来查询数据库表中的记录。 查询关键字&#xff1a;SELECT 查询操作是所有SQL语句当中最为常见&#xff0c;也是最为重要的操作。在一个正常的业务系统中&#xff0c;查询操作的使用频次…...

如何使用Java和RabbitMQ实现延迟队列(方式二)?

前言 昨天写了一篇关于Java和RabbitMQ使用插件实现延迟队列功能的文章&#xff0c;今天来讲下另外一种方式&#xff0c;不需要RabbitMQ的插件。 前期准备&#xff0c;需要安装好docker、docker-compose的运行环境。 需要安装RabbitMQ的可以看下面这篇文章。 如何使用PHP和R…...

String.valueOf() 将各种数据类型的值转换为它们的字符串

String.valueOf() 是 Java 中 String 类的一个静态方法&#xff0c;用于将各种数据类型的值转换为它们的字符串表示形式。这个方法在多种情况下都非常有用&#xff0c;特别是当你需要将非字符串类型的值转换为字符串时。 方法签名 String.valueOf() 方法有多个重载版本&#…...

2024-04-08 NO.6 Quest3 自定义交互事件

文章目录 1 交互事件——更改 Cube 颜色2 交互事件——创建 Cube2.1 非代码方式2.2 代码方式 ​ 在开始操作前&#xff0c;我们导入上次操作的场景&#xff0c;相关介绍在 《2024-04-08 NO.5 Quest3 手势追踪进行 UI 交互-CSDN博客》 文章中。 1 交互事件——更改 Cube 颜色 …...

素描进阶:深入探索如何表现石膏像的质感

​素描进阶&#xff1a;深入探索如何表现石膏像的质感 素描&#xff0c;作为一种古老而经典的绘画方式&#xff0c;历来都被视为是艺术家们探索世界、理解形式与质感的重要工具。而在素描的过程中&#xff0c;如何精准地捕捉并表现物体的质感&#xff0c;是每位艺术家都需要深…...

flutter组件_AlertDialog

官方说明&#xff1a;A Material Design alert dialog. 翻译&#xff1a;一个材料设计警告对话框。 作者释义&#xff1a;显示弹窗&#xff0c;类似于element ui中的Dialog组件。 AlertDialog的定义 const AlertDialog({super.key,this.icon,this.iconPadding,this.iconColor,t…...

供应链领域主题:生产制造关键术语和系统

BOM&#xff08;Bill of Material&#xff09;物料清单 BOM&#xff08;Bill of Material&#xff09;物料清单&#xff0c;是计算机可以识别的产品结构数据文件&#xff0c;也是ERP的主导文件。BOM使系统识别产品结构&#xff0c;也是联系与沟通企业各项业务的纽带。ERP系统中…...

k8s_入门_kubelet安装

安装 在大致了解了一些k8s的基本概念之后&#xff0c;我们实际部署一个k8s集群&#xff0c;做进一步的了解 1. 裸机安装 采用三台机器&#xff0c;一台机器为Master&#xff08;控制面板组件&#xff09;两台机器为Node&#xff08;工作节点&#xff09; 机器的准备有两种方式…...

主干网络篇 | YOLOv5/v7 更换骨干网络之 HGNetv2 | 百度新一代超强主干网络

本改进已融入到 YOLOv5-Magic 框架。 论文地址:https://arxiv.org/abs/2304.08069 代码地址:https://github.com/PaddlePaddle/PaddleDetection 中文翻译:https://blog.csdn.net/weixin_43694096/article/details/131353118 文章目录 HGNetv2网络结构1.1 主干网络1.2 颈部…...

JUC:ScheduledThreadPoolExecutor 延迟任务线程池的使用

文章目录 ScheduledThreadPoolExecutortimer&#xff08;不建议用&#xff09;ScheduledThreadPoolExecutor处理异常应用 ScheduledThreadPoolExecutor timer&#xff08;不建议用&#xff09; timer也可以进行延迟运行&#xff0c;但是会有很多问题。 比如task1运行时间超过…...

js str字符串和arr数组互相转换

js str字符串和arr数组互相转换 字符串转为数组 1、split()方法 返回的是原字符串的数组 var str "hello"; var arr str.split(""); console.log(arr); //输出["h", "e", "l", "l", "o"]2、Ar…...

计算机网络——40各个层次的安全性

各个层次的安全性 安全电子邮件 Alice需要发送机密的报文m给Bob Alice 产生随机的对称秘钥&#xff0c; K s K_s Ks​使用 K s K_s Ks​对报文进行加密&#xff08;为了效率&#xff09;对 K s K_s Ks​使用Bob的公钥进行加密发送 K s ( m ) K_s(m) Ks​(m)和 K B ( K S ) K…...

OpenHarmony实战:Combo解决方案之W800芯片移植案例

本方案基于OpenHarmony LiteOS-M内核&#xff0c;使用联盛德W800芯片的润和软件海王星系列Neptune100开发板&#xff0c;进行开发移植。 移植架构采用Board与SoC分离方案&#xff0c;支持通过Kconfig图形化配置编译选项&#xff0c;增加玄铁ck804ef架构移植&#xff0c;实现了…...

【数据结构】数组(稀疏矩阵、特殊矩阵压缩、矩阵存储、稀疏矩阵的快速转置、十字链表)

稀疏矩阵、矩阵压缩、稀疏矩阵的快速转置、十字链表 目录 稀疏矩阵、矩阵压缩、稀疏矩阵的快速转置、十字链表1.数组2.数组的顺序表示和实现3.特殊矩阵的压缩存储&#xff08;1&#xff09;. 上三角矩阵—列为主序压缩存储&#xff08;2&#xff09;. 下三角矩阵—**行为主序压…...

Python项目依赖管理:如何用pipreqs精准生成requirements.txt(附常见问题解决)

Python项目依赖管理实战&#xff1a;从pipreqs到高效协作的全链路优化 在Python项目开发中&#xff0c;依赖管理就像建筑的地基——它不显眼却决定了整个项目的稳定性。想象一下这样的场景&#xff1a;你花了三天时间调试一个诡异的问题&#xff0c;最后发现只是因为测试环境缺…...

Ubuntu 20.04下Mathematica 12.3安装全攻略(附Jupyter集成技巧)

Ubuntu 20.04下Mathematica 12.3安装与Jupyter集成实战指南 在科研计算与符号数学领域&#xff0c;Mathematica始终保持着不可替代的地位。对于Ubuntu用户而言&#xff0c;安装特定历史版本&#xff08;如12.3&#xff09;往往比最新版本更具挑战性——官方默认提供最新版下载&…...

Claude Code开源第一人,竟是华人辍学博士!CC之父回应:纯手误

51万行Claude Code代码全网裸奔&#xff0c;背后泄密第一人竟是他。就在刚刚&#xff0c;CC之父回应来了&#xff1a;是人&#xff0c;不是Bun。爆出Claude Code源码第一人&#xff0c;竟被全网扒出来了&#xff01;3月31日凌晨4点23分&#xff0c;安全研究员Chaofan Shou在X上…...

嵌入式开发关键技术演进与实战经验分享

1. 嵌入式开发的行业现状与核心挑战2023年的嵌入式开发领域呈现出明显的多元化发展趋势。作为一名从业超过十年的嵌入式工程师&#xff0c;我观察到这个行业正在经历从传统单机设备向智能化、网络化方向的快速转型。根据AspenCore最新发布的行业调查报告&#xff0c;目前超过30…...

米哈游面经规律总结:我看了大量面经,挂掉的人都卡在同一层

米哈游面经规律总结&#xff1a;我看了大量面经&#xff0c;挂掉的人都卡在同一层 offer直通车-校招大礼包获取&#xff1a;入口 几乎所有挂掉的人&#xff0c;都挂在同一个地方 最近整理米哈游的面经&#xff0c;看到一个反复出现的场面。 面试官问&#xff1a;"说说智…...

【OpenClaw从入门到精通】第54篇:物理隔离“龙虾”——傻福虾盘与Docker沙箱实战对比(2026实测版)

摘要:2026年工信部NVDB平台及CNCERT指南明确要求:OpenClaw需在隔离环境中部署,严禁在办公设备直接运行。本文聚焦两大主流隔离方案——物理隔离(闲置旧电脑/专用硬件盒子)与Docker沙箱,系统拆解从原理到实操的全流程。包含3套完整部署案例、15+安全配置命令、容器逃逸风险…...

TX12 + ExpressLRS 915MHz RC链路优化与EdgeTX固件升级实战

1. 为什么选择TX12搭配ExpressLRS 915MHz系统 玩无人机的朋友都知道&#xff0c;遥控链路就像风筝线&#xff0c;距离和稳定性直接决定飞行体验。我之前用2.4GHz的RadioLink套装&#xff0c;飞到500米就开始心跳加速——信号时断时续&#xff0c;每次返航都像在赌运气。换成TX1…...

随着AI和电商重塑消费者购买行为,全球美妆市场增长10%

随着数字优先和AI影响下的全球电商加速发展&#xff0c;线上销售额增速达到线下门店的6倍 全球消费者情报领军企业NielsenIQ (NYSE:NIQ)今日发布《2026年美妆行业现状报告》。报告显示&#xff0c;全球美妆市场同比增长10%&#xff0c;电商销售额增速达到线下门店的6倍。该结果…...

革新游戏配置体验:PCL2-CE社区版,Minecraft玩家的效率神器

革新游戏配置体验&#xff1a;PCL2-CE社区版&#xff0c;Minecraft玩家的效率神器 PCL2-CE社区版是一款开源游戏配置工具&#xff0c;它不仅能让玩家轻松管理Minecraft游戏环境&#xff0c;更能通过智能时间管理、跨平台同步等功能&#xff0c;为玩家节省宝贵的游戏时间&#…...

攻克模电难点(一):多级放大电路与差动放大电路实战解析

1. 多级放大电路的设计基础 第一次接触多级放大电路时&#xff0c;我被各种耦合方式绕得头晕。直到在实验室烧坏几个三极管后&#xff0c;才真正理解其中的门道。多级放大电路的核心思想很简单&#xff1a;把多个单级放大电路像搭积木一样连接起来&#xff0c;但实际设计时却要…...