【C++链表】

news2024/11/28 2:33:47

目录

  • 前言
  • 一、搭建链表实现的框架
  • 二、链表的构造函数
  • 三、链表的尾插
  • 四、链表的遍历(重点)
    • 迭代器的遍历
    • const修饰的迭代器
  • 五、代码实现

前言

最近用C++写了一下list的基本功能,感触颇深。本以为会跟之前用C写list一样会很轻松,没想到更难了。要考虑的东西跟多了,而且模板报错真的太恶心了(小小吐槽一下,其实就是自己学的不够扎实,还得练呐)。下面的内容是我自己在写链表时的顺序及注意点。

一、搭建链表实现的框架

在这里插入图片描述

二、链表的构造函数

当把一个框架搭建好后,第一步就是写的构造函数。
在这里插入图片描述

三、链表的尾插

构造函数写完后就要开始往链表里插入数据了,所以第三步我开始写链表的尾插(这里都是比较简单的跟之前C语言没什么两样)。我懒得画图解释了,直接上代码。

void push_back(const T& val)
{
	Node* newnode = new Node(val);
	Node* tail = _head->_prev;

	//链接
	tail->_next = newnode;
	newnode->_prev = tail;

	newnode->_next = _head;
	_head->_prev = newnode;
}

四、链表的遍历(重点)

迭代器的遍历

先看看库实现的链表我们是怎么拿过来用的。
在这里插入图片描述
为了完成跟库里一样,我们还需要设计迭代器。
在这里插入图片描述
重载*、++其实很简单。但是重载!=有个比较坑的地方。
在这里插入图片描述

const修饰的迭代器

首先要清楚我们期望的const修的的迭代器是具有怎么的功能。
我们期望被const修饰过的迭代器指向的内容不要被修改,但是可以通过重载的++修改本身。
那这样行不行?如:

typedef const _list_iterator<T> const_iterator;

在这里插入图片描述
在这里插入图片描述

五、代码实现

其他的功能其实都不难,都很好写。所以不想画图解释了,直接上代码。

#pragma once
#include<iostream>
using namespace std;
namespace Ting
{
	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)
		{}
		bool operator!=(const self& it)//这个const有说法
		{
			return _node != it._node;
		}
		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		self operator++(int)
		{
			_list_iterator<T> temp(*this);
			_node = _node->_next;
			return temp;
		}
		Ref operator*()
		{
			return _node->_val;
		}
		Ptr operator->()
		{
			return &(_node->_val);
		}
	};

	template<class T>
	class _list
	{
		typedef _list_node<T> Node;
	public:
		typedef _list_iterator<T,T&,T*> iterator;
		//如何设计const迭代器
		typedef _list_iterator<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;
		}

		_list()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		
		void push_back(const T& val=T())
		{
			Node* newnode = new Node(val);
			Node* tail = _head->_prev;

			//链接
			tail->_next = newnode;
			newnode->_prev = tail;

			newnode->_next = _head;
			_head->_prev = newnode;
		}

		void push_front(const T& val = T())
		{
			insert(begin(), val);
		}

		void pop_back()
		{
			Node* tail = _head->_prev;
			Node* newtail = tail->_prev;

			_head->_prev = newtail;
			newtail->_next = _head;
			
		}

		void pop_front()
		{
			erase(begin());
		}

		iterator insert(iterator pos, const T& val = T())
		{
			Node* cur = pos._node;
			Node* pre = cur->_prev;
			Node* newnode =new Node(val);

			pre->_next = newnode;
			newnode->_prev = pre;

			newnode->_next = cur;
			cur->_prev = newnode;

			return newnode;
		}

		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* pre = cur->_prev;
			Node* next = cur->_next;

			pre->_next = next;
			next->_prev = pre;
			delete cur;

			return next;
		}

		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it=erase(it);
			}
		}

		//拷贝构造
		_list(_list<T>& lt)
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;

			iterator it = lt.begin();
			while (it != lt.end())
			{
				push_back(*it);
				++it;
			}
		}

		void swap(_list<T>& lt)
		{
			std::swap(_head, lt._head);
		}

		_list<T>& operator=(_list<T> lt)
		{
			swap(lt);
			return *this;
		}

		~_list()
		{
			clear();
		}
	private:
		Node* _head;
	};
}

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

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

相关文章

【数据结构】C--单链表(小白入门基础知识)

前段时间写了一篇关于顺序表的博客&#xff0c;http://t.csdn.cn/0gCRp 顺序表在某些时候存在着一些不可避免的缺点: 问题&#xff1a; 1. 中间 / 头部的插入删除&#xff0c;时间复杂度为 O(N) 2. 增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不…

第110天:免杀对抗-GOC#反VT沙盒逆向调试参数加载资源分离混淆加密

知识点 #知识点&#xff1a; 1、C#-混淆&分离&反调试 2、GO-混淆&分离&反调试 3、成品程序-包含反调试VT#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳…

Progressive Dual-Branch Network for Low-Light Image Enhancement 论文阅读笔记

这是22年中科院2区期刊的一篇有监督暗图增强的论文 网络结构如下图所示&#xff1a; ARM模块如下图所示&#xff1a; CAB模块如下图所示&#xff1a; LKA模块其实就是放进去了一些大卷积核&#xff1a; AFB模块如下图所示&#xff1a; 这些网络结构没什么特别的&#xf…

【团队协作开发】将Gitee项目导入到本地IDEA中出现根目录不完整的问题解决(已解决)

前言&#xff1a;在团队协作开发过程中&#xff0c;通常我们的Gitee完整项目中会包含很多内容&#xff1a;后端代码、前端代码、项目结构图、项目文档等一系列资产。 将Gitee项目导入到本地IDEA中&#xff0c;通常会出现根目录不完整的问题。这是因为项目里面包含了后端代码、前…

Matlab的GUI设计

文章目录 AppDesigner各个版本的特点mlapp文件基本格式AppDesigner的回调函数常见控件的属性MVC模式MVC模式设计GUIMVC简单使用 其他让app designer置顶将Guide的GUI导出为m文件将app编译为exe将app中的多个控件组合在一起 AppDesigner 20200328 各个版本的特点 在2017b版本中…

用 Node.js 手写 WebSocket 协议

目录 引言 从 http 到 websocekt 的切换 Sec-WebSocket-Key 与 Sec-WebSocket-Accept 全新的二进制协议 自己实现一个 websocket 服务器 按照协议格式解析收到的Buffer 取出opcode 取出MASK与payload长度 根据mask key读取数据 根据类型处理数据 frame 帧 数据的发…

【C++模拟实现】string的模拟实现

【C模拟实现】string的模拟实现 目录 【C模拟实现】string的模拟实现string模拟实现的标准代码string模拟实现中的要点string构造函数的实现赋值运算符重载迭代器的实现对流插入和流提取运算符的重载find函数的实现insert函数的实现 作者&#xff1a;爱写代码的刚子 时间&#…

MySQL视图概念及作用、操作语法

1.什么是视图 在数据库中有一些用户的敏感数据字段不方便展示&#xff0c;需要隐藏时&#xff0c;这时候就可以利用视图这个概念来实现。 2.视图操作 如何对视图里的数据进行增删改操作呢&#xff1f; 可以直接通过insert语句向视图里面插入数据&#xff0c;语法和向表里插…

移动测试(二)

功能测试点 用户使用习惯 权限问题 硬件问题 比如双卡双待、摄像头、GPU等。 操作习惯 用户常用的有菜单键、Home键、返回键、Home键长按&#xff08;显示当前进程列表&#xff09;、调整音量、待机等。相应的作为测试工程师我们需要考虑的项就变成了&#xff1a; • 应用中的…

Docker——基本管理

Docker 基本管理 Docker——基本管理 一、Docker 概述1.Docker的设计理念2.容器的优势3.Docker与虚拟机的区别4.容器在内核中支持2种重要技术5.Docker核心概念5.1 镜像5.2 容器5.3 仓库 二、安装 Docker1.关机防火墙2.安装依赖包3.设置阿里云镜像源4.安装 Docker-CE并设置为开…

PostgreSQL 的事务管理和并发控制机制解析

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Istio Pilot源码学习(三):xDS的异步分发

本文基于Istio 1.18.0版本进行源码学习 5、xDS的异步分发 DiscoveryService主要包含下述逻辑&#xff1a; 启动GRPC Server并接收来自Envoy端的连接请求接收Envoy端的xDS请求&#xff0c;从ConfigController和ServiceController中获取配置和服务信息&#xff0c;生成响应消息…

使用 ChatGPT 碰到的坑

最近在使用 ChatGPT 的时候碰到一个小坑&#xff0c;因为某些特殊情况我需要使用 syslog 向 logbeat 中发送日志。 由于这是一个比较古老的协议&#xff0c;确实也没接触过&#xff0c;所以就想着让 ChatGPT 帮我生成个例子。 原本我已经在 Go 中将这个流程跑通&#xff0c;所…

快速排序qsort讲解

hello大家好&#xff0c;我是c语言boom家宝&#xff0c;今天为大家分享的博客内容是qsort快速排序&#xff0c;简称快排的一个知识点的讲解。 在讲到快排之前&#xff0c;允许博主先提一嘴冒泡排序。大家在c语言的学习过程中&#xff0c;冒泡排序是必不可少会学习到的一个思想&…

Kafka - Primie Number of Partitions Issue Consumer Group Rebalance

文章目录 生产者&#xff1a;将数据写入 Kafka 的客户端。 消费者&#xff1a;从 Kafka 中读取数据的客户端。 Topic&#xff1a;Kafka 中用于组织和存储数据的逻辑概念&#xff0c;类似于数据库表。 Record&#xff1a;发送到 Topic 的消息称为 Record。 Partition&#x…

基于深度学习的高精度交通信号灯检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度交通信号灯检测识别可用于日常生活中检测与定位交通信号灯目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的交通信号灯目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检…

斯坦福数据挖掘教程·第三版》读书笔记(英文版)Chapter 13 Neural Nets and Deep Learning

来源&#xff1a;《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 13 Neural Nets and Deep Learning In this chapter, we shall consider the design of neural nets, which are collections of perceptrons, or nodes, where the outputs of one rank (or lay…

C# 学习笔记

不再是学生了&#xff0c;成了社畜了&#xff0c;公司主要技术栈是C# 大一时候学C#学的很迷糊&#xff0c;总要重新学一下 入职已经20天了&#xff0c;也开始上手简单增删改查了 记录了一些C#相关的东西&#xff0c;只是还没有系统整理 WinForm 控件命名规范 ADO.NET 连接…

爬虫-微博个人主页的获取

我们在利用爬虫爬取微博个人主页的时候&#xff0c;我们需要获取到个人页面的cookie才能进入到微博的个人主页&#xff0c;否则的话将会是一直跳转到登录页面而导致不能进入个人主页。 import urllib.request url #自己微博个人主页的源代码 headers {User-Agent:Mozilla/5.…

办公软件ppt的制作

毕业找工作太难了&#xff0c;赶紧多学点什么东西吧&#xff0c;今天开始办公软件ppt的制作学习。 本文以WPS作为默认办公软件&#xff0c;问为什么不是PowerPoint&#xff0c;问就是没钱买不起&#xff0c;绝对不是不会破解的原因。 一.认识软件 在快捷工具栏中顾名思义就是一…