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

波奇学C++:stl的list模拟实现

list是双向带头链表。所以迭代器end()相当于哨兵卫的头。

list不支持+和[]重载,原因在于list空间不是连续的,+和[]的代价比较大。

访问第n个节点,只能用for循环,++来实现

list<int> l;
l.push_back(0);
l.push_back(1);
l.push_back(2);
l.push_back(3);
auto li=l.begin();
//访问第3个节点
for(size_t i=0;i<3;i++)
{li++;
}

list的insert不会失效,但是erase会迭代器失效。

list是双向迭代器

迭代器可以简单分为:单向迭代器(forward)++,双向迭代器(bidirectional) ++/-- 随机迭代器(random acess)+/-/++/--

不同的数据结构的迭代器决定了可以使用不同的算法。其中随机迭代器代器的范围最广,可以用的算法最多。

std:sort只能是随机迭代器用,list不能使用,list也有自己的sort算法但是效率并不高。

list实现

大概思路先不考虑迭代器,链表分为两个类,一个类表示节点,另外一个类表示链表。

节点模板类

template<class T>struct list_node{list_node<T>* _next;list_node<T>* _prev;T _val;list_node(const T& val = T()):_next(nullptr),_prev(nullptr),_val(val){}};

这里有个注意的点,模板类的类名不是类型,list_node只是类名,不是对应的自定义类型,所以是

list_node<T>* _next;而不是list_node* _next。

编译器优化 

拷贝构造写类名也可以

模拟实现的代码

namespace my_list
{template<class T> struct list_node{list_node<T>* _prev;list_node<T>* _next;T _val;list_node(const T& val=T()):_next(nullptr),_prev(nullptr),_val(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){}Ref operator*(){return _node->_val;}self& operator++(){_node = _node->_next;return *this;}self& operator--(){_node = _node->_prev;return *this;}bool operator!=(const self& it){return _node != it._node;}self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}Ptr operator->(){return &_node->_val;}};template<class T>class list{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 _head->_next; }iterator end(){return _head;}const_iterator const_begin(){return _head->_next;}const_iterator const_end(){return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;}list(){empty_init();}~list(){clear();delete _head;_head = nullptr;}list(const list<T>& lt){empty_init();for (auto& e : lt){push_back(e);} }void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}list<T>& operator=(list<T> lt){swap(lt);return *this;}~list(){clear();delete _head;_head = nullptr;}void 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 pop_back(){erase(--end());}void pop_begin(){erase(begin());}iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);prev->_next = newnode;newnode->_next = cur;cur->_prev = newnode;newnode->_prev = prev;return newnode;}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return next;}void clear(){iterator it = begin();while (it != end()){it=erase(it);}}size_t size(){size_t sz = 0;iterator it = begin();while (it != end()){sz++;}return sz;}private:Node* _head;Node* _tail;};
}

相关文章:

波奇学C++:stl的list模拟实现

list是双向带头链表。所以迭代器end()相当于哨兵卫的头。 list不支持和[]重载&#xff0c;原因在于list空间不是连续的&#xff0c;和[]的代价比较大。 访问第n个节点&#xff0c;只能用for循环&#xff0c;来实现 list<int> l; l.push_back(0); l.push_back(1); l.pu…...

Flask 项目结构

前面我们了解了 Flask 框架的特性和一些用法&#xff0c;比如创建一个简单应用、做些页面&#xff0c;以及增加鉴权模块等&#xff0c;如果要将 Flask 用于实际项目开发&#xff0c;还需要了解一下 Flask 项目结构。 Flask 是一个轻量级的 Web 框架&#xff0c;扩展性强&#…...

云计算在IT领域的发展和应用

文章目录 云计算的发展历程云计算的核心概念云计算在IT领域的应用1. 基础设施即服务&#xff08;IaaS&#xff09;&#xff1a;2. 平台即服务&#xff08;PaaS&#xff09;&#xff1a;3. 软件即服务&#xff08;SaaS&#xff09;&#xff1a; 云计算的拓展应用结论 &#x1f3…...

8年测试经验之谈 —— 接口自动化测试requests

1.什么是requests&#xff1f; requests是一个Python第三方库&#xff0c;处理URL资源特别方便 2.安装requests pip3 install requests 如果遇到Permission denied安装失败&#xff0c;请加上sudo重试 3.使用requests 3.1get请求方法 3.1.1基本的get请求 import reques…...

求助:vue从后端获取数据,如何对获得的数据进行拆分?

从后端获取数据格式如下&#xff1a; { "count": 3, "lists": [ { "id": 2, "name_id": 4, "name": "4: 2201030019: 张四", }, { …...

html5拖拽文件上传需阻止默认事件

至少阻止下列3个事件的默认行为才能实现文件拖拽上传 var bdocument.getElementById(box) b.ondragenter(e)>{e.preventDefault()console.log(aaa,e.dataTransfer.files); } b.ondragover(e)>{e.preventDefault()console.log(bb,e.dataTransfer.files); }b.ondrop(e)>…...

深入剖析Kubernetes之Pod基本概念(一)

文章目录 Pod 中重要字段Pod 的生命周期 Pod&#xff0c;而不是容器&#xff0c;才是 Kubernetes 项目中的最小编排单位。将这个设计落实到 API 对象上&#xff0c;容器&#xff08;Container&#xff09;就成了 Pod 属性里的一个普通的字段。那么&#xff0c;到底哪些属性属于…...

idea 对JavaScript进行debug调试

文章目录 1.新增 JavaScript Debug 配置2.配置访问地址3.访问url. 打断点测试 前言 : 工作中接手别人的前端代码没有注释&#xff0c;看浏览器的network或者console切来切去&#xff0c;很麻烦&#xff0c;可以试试idea自带的javscript debug功能。 1.新增 JavaScript Debug 配…...

npm init

1、什么是npm init npm是开源 JavaScript 包管理器&#xff0c;允许 JavaScript 开发人员分享和重用代码。npm init是一种在创建新的npm包时使用的命令&#xff0c;它将提示你填写一些信息以便在package.json文件中创建初始配置。 2、为什么要使用npm init初始化项目 在node…...

微信小程序开发教学系列(6)- 数据缓存与本地存储

第六章 数据缓存与本地存储 在开发微信小程序时&#xff0c;我们通常会面临一个问题&#xff1a;如何在不重复请求接口的情况下&#xff0c;将数据保存在本地&#xff0c;提高用户体验并减少网络请求的次数。这就需要我们学会使用数据缓存和本地存储的技巧。本章将介绍在微信小…...

跟我学c++中级篇——模板的基础术语说明

一、类模板术语 1、模板的特化 模板的特化也叫具体化&#xff0c;非常容易理解&#xff0c;就是把模板中的模板参数给定具体的类型。看下面的例子&#xff1a; //模板 template <typename T,typname N> class Data {}; //特化 template<> class Data<int,int&…...

最新Win10离线安装.NET Framework 3.5的方法(附离线包2022/3/22)

win10系统安装软件时&#xff0c;可能需要.net framework3.5的运行环境&#xff0c;当我们安装某些软件的时候会提示“你的电脑上的应用需要使用以下Windows功能:.NET Framework 3.5(包括.NET 2.0和3.0)。如果系统默认的是4.0以上的版本&#xff0c;当软件需要.net framework3.…...

最新docker多系统安装技术

在Ubuntu操作系统中安装Docker 在Ubuntu操作系统中安装Docker的步骤如下。 1&#xff0e;卸载旧版本Docker 卸载旧版本Docker的命令如下&#xff1a; $ sudo apt-get remove docker docker-engine docker.io 2&#xff0e;使用脚本自动安装 在测试或开发环境中&#xff0…...

系统架构设计高级技能 · 云原生架构设计理论与实践

系列文章目录 系统架构设计高级技能 软件架构概念、架构风格、ABSD、架构复用、DSSA&#xff08;一&#xff09;【系统架构设计师】 系统架构设计高级技能 系统质量属性与架构评估&#xff08;二&#xff09;【系统架构设计师】 系统架构设计高级技能 软件可靠性分析与设计…...

Springboot集成RocketMQ——简单使用

目录 1.MQ选型 2.RocketMQ基本架构 3.Springboot集成RocketMQ 4.顺序消息 5.延时消息 6.事务消息 1.MQ选型 目前市面上的MQ选型&#xff1a;主要分为3个类型 Kafka&#xff1a;吞吐量大&#xff0c;且性能好&#xff0c;集群高可用&#xff1b;会丢失数据&#xff0c;功…...

第一百二十四回 Flexible组件

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了扩展内容相关的知识&#xff0c;本章回中将介绍 Flexible组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在前面章回中介绍了扩展列表相关的内容&#xff0c;当页面中其它组件和扩展列表一起使…...

关于stm32推挽带有上下拉电阻的思考、IO口驱动能力是什么

1、发现推挽带有上下拉电阻 1.1、stm32手册 记忆中推挽是不需要上下拉的&#xff0c;没关注过&#xff0c;但是我真的理解上下拉吗&#xff0c;下图来自stm32f4的中文版和英文版的数据手册&#xff0c;没有翻译错&#xff0c;就是“推挽带有上下拉的能力”。 1.2、查找相关信…...

考研408 | 【操作系统】 内存管理

内存的基础 内存和内存的作用&#xff1a; 几个常用的数量单位&#xff1a; 指令的工作原理&#xff1a; 问题&#xff1a;如何将指令中的逻辑地址转换为物理地址&#xff1f; 解决办法&#xff1a;装入的三种方式 1.绝对装入 2.可重定位装入 3.动态重定位 从写程序到程…...

C# 工厂模式

一、概述 工厂模式&#xff08;Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的最佳方式。在C#中&#xff0c;工厂模式通过定义一个公共接口或抽象类来创建对象&#xff0c;而具体的对象创建则由工厂类来实现。 工厂模式主要包含三个角色…...

在云服务器上安装Jenkins

说明&#xff1a;Jenkins是一个部署项目的平台&#xff0c;通过Jenkins可以省去从项目开发–>部署项目之间的所有流程&#xff0c;做到代码提交即上线。本文介绍在云服务CentOS上安装Jenkins。 前提 安装Jenkins之前&#xff0c;先要在云服务上安装JDK、Maven、Git&#x…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾&#xff1a; 在上一篇《React核心概念&#xff1a;State是什么&#xff1f;》中&#xff0c;我们学习了如何使用useState让一个组件拥有自己的内部数据&#xff08;State&#xff09;&#xff0c;并通过一个计数器案例&#xff0c;实现了组件的自我更新。这很棒&#…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学

一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件&#xff0c;其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时&#xff0c;价带电子受激发跃迁至导带&#xff0c;形成电子-空穴对&#xff0c;导致材料电导率显著提升。…...