C/C++ list模拟
模拟准备
避免和库冲突,自己定义一个命名空间
namespace yx
{template<class T>struct ListNode{ListNode<T>* _next;ListNode<T>* _prev;T _data;};template<class T>class list{typedef ListNode<T> Node;public:private:Node* _head;};}
这里的ListNode类为什么用struct呢?
知识点:
class:如果类里有公有,有私有,建议用
struct:如果一个类,全部成员不做访问限定,全公有,建议用
因为下面的list类是要经常访问ListNode的,所以建议用struct
模拟实现
模板ListNode的构造
封装节点的数据
template<class T>
struct ListNode
{ListNode<T>* _next;ListNode<T>* _prev;T _data;ListNode(const T& data):_next(nullptr), _prev(nullptr),_data(data){}
};
list的构造
void list()
{//哨兵位_head = new Node;_head->next = _head;_head->prev = _head;
}
定义一个哨兵位,自己指向自己。

push_back( )
尾插

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 和 tail都是哨兵位(head)
迭代器
说起迭代器,我们先考虑如何遍历链表吧。
我们是否可以像vector那样呢?
typedef Node* iterator;
当然是不可以的。
vector的空间是连续的,而list的空间不连续,那我们如何获取Node*呢?
定义迭代器类
我们可以定义一个类,把节点_node封装起来,来弥补空间不连续的缺陷,能像vector那样一样来进行访问。
template<class T>
class ListIterator
{typedef ListNode<T> Node;Node* _node;
};
template定义的模板参数只能供当前类或当前函数用
而且我们可以在这个类里重载想要的东西
使用时,我们就可以给每个类规范这个迭代器使用的名字,方便我们使用
typedef ListIterator<T> iterator;
template<class T>
class ListIterator
{typedef ListNode<T> Node;typedef ListIterator<T> self; // 返回自己Node* _node;self& operator++(){_node = _node->_next;return *this;//返回节点自己}T& operator*(){return _node->_data;//返回数据,数据类型为T}bool operator!=(const self& it){return _node != it._node;}};
iterator begin( ) 、 iterator end( )
我们实现了迭代器,我们来实现一下链表的头指针和尾指针吧

在list类里
iterator begin()
{//iterator it(_head->_next);//return it;//我们采用匿名对象return iterator(_head->_next);
}
iterator end()
{return iterator(_head;
}
测试通过

operator->( )
T* operator->()
{return &_node->_data;
}
我们来测试一下下面的代码
struct pos
{int _row;int _col;pos(int row = 0, int col = 0):_row(row), _col(col){}
};void test2()
{list<pos> lt1;lt1.push_back(pos(100, 100));lt1.push_back(pos(200, 100));lt1.push_back(pos(300, 100));list<pos>::iterator it = lt1.begin();while (it != lt1.end()){cout << (*it)._row << ":" << (*it)._col << " ";cout << it->_row << ":" << it->_col << " ";++it;}cout << endl;}
第一种用的是对象.成员
第二种指针->成员
第一种比较好理解,it调用operator*(),返回data数据,也就是pos,然后pos._row,pos._col来访问
第二种比较绕,这里为了可读性,省略可一个->,但如果写两个的话不符合语法,于是
cout << it.operator->()->_row << ":" << it.operator->()->_col << " ";
第一个->是operator重载的,而第二个是原生指针的解引用

const迭代器
不能是普通迭代器前面+const修饰。
如:const iterator const
const迭代器目标本身可以修改,指向的内容不能修改 ,
类似:const T* p
p可以修改,*p不能修改
因为T* 和 T&,这里我们可以写一个和迭代器一样的const迭代器类,但我们也可以类模板,传不同的参数,形成不同的类,让编译器帮我们实现。避免了写连个差不多重复的类,减少代码量


insert( )
//在pos前插入val
iterator insert(iterator pos, const T& val)
{Node* pNewNode = new Node(val);Node* pCur = pos._node;pNewNode->_prev = pCur->_prev;pNewNode->_next = pCur;pNewNode->_prev->_next = pNewNode;pCur->_prev = pNewNode;return iterator(pNewNode);
}
erase( )
//删除pos节点
iterator erase(iterator pos)
{Node* pDel = pos._node;Node* pRet = pDel->_next;pDel->_prev->_next = pDel->_next;pDel->_next->_prev = pDel->_prev;delete pDel;return iterator(pRet);
}
clear()
void clear()
{Node* cur = _head->_next;while (cur != _head){//从头开始删(从左向右)_head->_next = cur->_next;delete cur;cur = _head->_next;}_head->_next = _head->_prev = _head;
}
~list()
~list()
{clear();delete _head;_head = nullptr;
}
相关文章:
C/C++ list模拟
模拟准备 避免和库冲突,自己定义一个命名空间 namespace yx {template<class T>struct ListNode{ListNode<T>* _next;ListNode<T>* _prev;T _data;};template<class T>class list{typedef ListNode<T> Node;public:private:Node* _…...
android studio开发
Kotlin 编程简介 | Android Basics Compose - First Android app | Android Developers (google.cn) 这是官网的教程,实现试一下。 之后进入课程 您的第一个 Kotlin 程序 (google.cn) 程序可以被视为一系列指示计算机或设备执行某项操作的指令,...
PostgreSQl 物化视图
物化视图(Materialized View)是 PostgreSQL 提供的一个扩展功能,它是介于视图和表之间的一种对象。 物化视图和视图的最大区别是它不仅存储定义中的查询语句,而且可以像表一样存储数据。物化视图和表的最大区别是它不支持 INSERT…...
Win10工具:批量word转png图片
首先声明这个小工具是小编本人开发的,无任何广告,会员收费机制等,永久使用。允许公司或个人使用,不允许倒卖,否则发现后会追究法律责任,毕竟开发不易。工具是用python开发的。 功能非常单一,就…...
期货量化交易客户端开源教学第八节——TCP通信服务类
private FReciveStr: AnsiString; {接收到的数据} IsConErr: Boolean; {网络连接是否失败} FSocket_LB: Integer; {TCP连接类别,0为交易,1为行情,2为查询} FRetryCount: Integer; {网络连接重试次数} FLoginErrEvent: TLoginErrEvent; {…...
bi项目笔记
1.bi是什么 bi项目就是商业智能系统,也就是数据可视画、报表可视化系统,如下图的就是bi项目了 2.技术栈...
金蝶云苍穹-插件开发(四)GPT开发相关插件
我只对GPT开发的相关插件进行讲解,因为我的是插件开发教程,关于GPT的一些提示词的写法,GPT任务的配置,请去金蝶云苍穹的文档和社区内学习。 GPT自定义操作 GPT自定义操作的代码的类要实现 IGPTAction 这个接口,这个接…...
【机器学习】精准农业新纪元:机器学习引领的作物管理革命
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀目录 🔍1. 引言📒2. 精准农业的背景与现状🍁精准农业的概念与发展历程🍂国内外精准农业实践案…...
一键掌握天气动态 - 基于Vue和高德API的实时天气查询
前言 本文将学习如何使用Vue.js快速搭建天气预报界面,了解如何调用高德地图API获取所需的天气数据,并掌握如何将两者有机结合,实现一个功能丰富、体验出色的天气预报应用 无论您是前端新手还是有一定经验,相信这篇教程都能为您带来收获。让我们一起开始这段精彩的Vue.js 高德…...
PostgreSQL修改最大连接数
在使用PostgreSQL 的时候,经常会遇到这样的错误提示, sorry, too many clients already,这是因为默认PostgreSQL最大连接数是 100, 一般情况下,个人使用时足够的,但是在生产环境,这个连接数是远远不够的&am…...
C# SqlSugar 如何使用Sql语句进行查询,并带参数进行查询,防注入
一般ORM查询单表数据已经是很简单的一种方式了 详情可以看我的另一篇文章:ORM C# 封装SqlSugar 操作数据库_sqlsugar 基类封装-CSDN博客 下面是介绍有些数据是需要比较复杂的SQL语句来进行查询的时候,则需要自行组装SQL语句来进行查询,下面…...
slf4j日志框架和logback详解
slf4j作用及其实现原理 SLF4J(Simple Logging Facade for Java)是一种日志框架的抽象层,它并不是一个具体的日志实现,而是一个接口或门面(Facade),旨在为各种不同的日志框架提供一个统一的API。…...
解决@Data与@Builder冲突的N种策略
前言 在Java项目中,Lombok的Data和Builder注解因其便捷性深受开发者喜爱,但两者并用时可能引发构造方法冲突。本文将全面解析这一问题的根源,并介绍包括利用实验性思路探讨的Tolerate概念在内的多种解决方案,确保您在实践中游刃有…...
一文看懂LUT(Lookup Table)查找表
文章目录 原理方法具体步骤和代码实现 查找表(Lookup Table,LUT)方法是一种通过预先计算并存储函数值来加速计算的方法。对于激活函数(例如ReLU),使用LUT可以在一定范围内通过查找预计算的值来近似函数计算…...
06 人以群分 基于邻域的协同过滤算法
这一讲我们将正式进入算法内容的学习。 推荐算法本质 推荐算法本质上是一一种信息处理方法,它将用户信息和物品信息处理后,最终输出了推荐结果。因为 05 讲中基于热门推荐、基于内容推荐、基于关联规则推荐等方法比较粗放,所以推荐结果往往…...
SQL性能下降的原因
一、SQL性能下降的原因 主要是性能下降SQL慢、执行时间长、等待时间长 不是一条SQL抓出来就要优化,在真实的生产环境下这种故障第一个要去复线,有可能去排查的时候没,所以没法复线。 可能需要它跑半天或者一天来缩小筛查的范围,…...
js的原型
原型: 1定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。 通过该构造函数产生的对象,以继承该原型的属性和方法。原型也是对象。 2.利用原型特点和概念,可以提取共有属性。 3.对象如…...
FastAPI 学习之路(三十七)元数据和文档 URL
实现前的效果 那么如何实现呢,第一种方式如下: from routers.items import item_router from routers.users import user_router""" 自定义FastApi应用中的元数据配置Title:在 OpenAPI 和自动 API 文档用户界面中作为 API 的…...
C 语言结构体
本博客涉及的结构体知识有: 1.0:结构体的创建和使用 2.0: typedef 关键字与#define 关键字的区别 3.0: 结构体成员的访问【地址访问与成员访问】 4.0: 结构体嵌套调用 5.0 数组访问赋值结构体成员 ...... 1.0:结构体的创建和使用 结…...
MySQl高级篇-主从复制
主从复制 复制的基本原理 slave会从master读取binlog来进行数据同步 MySQL复制过程分成三步: master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events;slave将master的binary log events拷贝到它的中继日志(r…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
