C++list的模拟实现

为了实现list,我们需要实现三个类

一、List的节点类

template<class T>
struct ListNode
{
	ListNode(const T& val = T())
		:_pPre(nullptr)
		,_pNext(nullptr)
		,_val(val)
	{}
	ListNode<T>* _pPre;
	ListNode<T>* _pNext;
	T _val;
};

二、List的迭代器类

template<class T, class Ref, class Ptr>
class ListIterator
{
	typedef ListNode<T>* PNode;
	typedef ListIterator<T, Ref, Ptr> Self;
public:
	ListIterator(PNode pNode = nullptr)
		:_pNode(pNode)
	{}
	ListIterator(const Self& l)
		:_pNode(l._pNode)
	{}
	T& operator*()
	{
		return _pNode->_val;
	}
	T* operator->()
	{
		return &(_pNode->_val);
	}
	Self& operator++()//前置++
	{
		_pNode = _pNode->_pNext;
		return *this;
	}
	Self operator++(int)//后置++
	{
		Self tmp(*this);
		_pNode = _pNode->_pNext;
		return tmp;
	}
	Self& operator--()
	{
		_pNode = _pNode->_pPre;
		return *this;
	}
	Self& operator--(int)
	{
		Self tmp(*this);
		_pNode = _pNode->_pPre;
		return tmp;
	}
	bool operator!=(const Self& l)
	{
		return _pNode != l._pNode;
	}
	bool operator==(const Self& l)
	{
		return _pNode == l._pNode;
	}
	PNode _pNode;
};

三、List类

1.数据定义相关

template<class T>
class list
{
	typedef ListNode<T> Node;
	typedef Node* PNode;
public:
	typedef ListIterator<T, T&, T*> iterator;
	typedef ListIterator<T, const T&, const T&> const_iterator;
private:
	void CreateHead()//初始化
	{
		_pHead = new Node;
		_pHead->_pNext = _pHead;
		_pHead->_pPre = _pHead;
		_size = 0;
	}
	PNode _pHead;//头指针
	size_t _size;
};

2.构造函数相关

public:
	///
	// List的构造
	list()
	{
		CreateHead();
	}
	list(int n, const T& value = T())
	{
		CreateHead();
		for (int i = 0; i < n; i++)
		{
			push_back(value);
		}
	}
	template <class Iterator>
	list(Iterator first, Iterator last)
	{
		CreateHead();
		while (first != last)
		{
			push_back(*first);
			first++;
		}
	}
	list(const list<T>& l)
	{
		CreateHead();
		for (auto& e : l)
		{
			push_back(e);
		}
	}
	list<T>& operator=(list<T> l)
	{
		swap(l);
		return *this;
	}
	~list()
	{
		clear();
		delete _pHead;
		_pHead = nullptr;
	}

3.迭代器相关

///
// List Iterator
iterator begin()
{
	return iterator(_pHead->_pNext);
}
iterator end()
{
	return iterator(_pHead);
}
const_iterator begin() const
{
	return const_iterator(_pHead->_pNext);
}
const_iterator end() const
{
	return const_iterator(_pHead);
}

4.容量相关

///
// List Capacity
size_t size()const
{
	return _size;
}
bool empty()const
{
	return _size == 0;
}

5.数据访问相关


// List Access
T& front()
{
	return _pHead->_pNext->_val;
}
const T& front()const
{
	return _pHead->_pNext->_val;
}
T& back()
{
	return _pHead->_pPre->_val;
}
const T& back()const
{
	return _pHead->_pPre->_val;
}

6.修改数据相关


// List Modify
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的节点
void insert(iterator pos, const T& val)
{
	PNode pcur = pos._pNode;
	PNode newnode = new Node(val);
	PNode prev = pcur->_pPre;
	newnode->_pNext = pcur;
	newnode->_pPre = prev;
	pcur->_pPre = newnode;
	prev->_pNext = newnode;
	_size++;
}
// 删除pos位置的节点,返回该节点的下一个位置
iterator erase(iterator pos)
{
	PNode pdel = pos._pNode;
	PNode prev = pdel->_pPre;
	PNode next = pdel->_pNext;
	next->_pPre = prev;
	prev->_pNext = next;
	delete pdel;
	_size--;
	return iterator(next);
}
void clear()
{
	iterator it = begin();
	while (it != end())
	{
		it = erase(it);
	}
}
void swap(list<T>& l)
{
	std::swap(_pHead, l._pHead);
	std::swap(_size, l._size);
}

四、测试一下我们自己写的List

所用测试程序test.cpp

#include"List.h"
using namespace std;
///
// 对模拟实现的list进行测试
// 正向打印链表
template<class T>
void PrintList(const bite::list<T>& l)
{
	auto it = l.begin();
	while (it != l.end())
	{
		cout << *it << " ";
		++it;
	}

	cout << endl;
}

// 测试List的构造
void TestBiteList1()
{
	cout << "-----------------TestBiteList1()-----------------" << endl;
	bite::list<int> l1;
	bite::list<int> l2(10, 5);
	PrintList(l2);

	int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	bite::list<int> l3(array, array + sizeof(array) / sizeof(array[0]));
	PrintList(l3);

	bite::list<int> l4(l3);
	PrintList(l4);

	l1 = l4;
	PrintList(l1);
}

// PushBack()/PopBack()/PushFront()/PopFront()
void TestBiteList2()
{
	cout << "-----------------TestBiteList2()-----------------" << endl;
	// 测试PushBack与PopBack
	bite::list<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	PrintList(l);

	l.pop_back();
	l.pop_back();
	PrintList(l);

	l.pop_back();
	cout << l.size() << endl;

	// 测试PushFront与PopFront
	l.push_front(1);
	l.push_front(2);
	l.push_front(3);
	PrintList(l);

	l.pop_front();
	l.pop_front();
	PrintList(l);

	l.pop_front();
	cout << l.size() << endl;
}

// 测试insert和erase
void TestBiteList3()
{
	cout << "-----------------TestBiteList3()-----------------" << endl;
	int array[] = { 1, 2, 3, 4, 5 };
	bite::list<int> l(array, array + sizeof(array) / sizeof(array[0]));

	auto pos = l.begin();
	l.insert(l.begin(), 0);
	PrintList(l);

	++pos;
	l.insert(pos, 2);
	PrintList(l);

	l.erase(l.begin());
	l.erase(pos);
	PrintList(l);

	// pos指向的节点已经被删除,pos迭代器失效
	cout << *pos << endl;

	auto it = l.begin();
	while (it != l.end())
	{
		it = l.erase(it);
	}
	cout << l.size() << endl;
}
int main()
{
	TestBiteList1();
	TestBiteList2();
	TestBiteList3();

	return 0;
}

测试结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年腾讯云服务器99元一年_老用户优惠续费不涨价

腾讯云99元一年服务器配置为轻量2核2G4M、50GB SSD盘、300GB月流量、4M带宽&#xff0c;新用户和老用户都可以购买&#xff0c;续费不涨价&#xff0c;续费价格也是99元一年。以往腾讯云优惠服务器都是新用户专享的&#xff0c;这款99元服务器老用户也可以购买&#xff0c;这是…

Spring Task 知识点详解、案例、源代码解析

简介&#xff1a;Spring Task 定时任务   所谓定时任务。就是依据我们设定的时间定时运行任务&#xff0c;就像定时发邮件一样&#xff0c;设定时间到了。邮件就会自己主动发送。 在Spring大行其道的今天&#xff0c;Spring也提供了其定时任务功能&#xff0c;Spring Task。同…

安装dalton过程中出现的pcre问题

在前面文章中&#xff0c;基于多种流量检测引擎识别pcap数据包中的威胁&#xff0c;并没有详细的说明dalton的安装。由于dalton提供了脚本./start-dalton.sh &#xff0c;执行之后会自动的安装各种依赖以及suricata&#xff0c;zeek&#xff0c;snort的容器环境。但是在实际执行…

编程新手必看!从零起步掌握Python的终极指南,Python简介(1)

1、Python语言的诞生 Python的作者&#xff0c;Guido von Rossum&#xff08;吉多范罗苏姆&#xff0c;中国Python程序员都叫他 龟叔&#xff09;&#xff0c;荷兰人。1982年&#xff0c;龟叔从阿姆斯特丹大学获得了数学和计算机硕士学位。然而&#xff0c;尽管他算得上是一位…

内存管理--柔性数组

本次讲的是&#xff0c;柔性数组&#xff0c;如果哪位小博客想要了解的更多&#xff0c;可以登录下面这个网站&#xff0c;了解详细内容 C语言结构体里的成员数组和指针 | 酷 壳 - CoolShellhttps://coolshell.cn/articles/11377.html 我们就听说过数组&#xff0c;听说过柔性数…

Excel求解二元一次方程

背景&#xff1a;如果想求解二元一次方程&#xff0c;常规方法就是联立方程求出一个未知数&#xff0c;然后带入任意一个等式。那么在excel里面应该怎么解决呢&#xff1f; 总所周知&#xff0c;大学里面会学矩阵行列式&#xff0c;二元一次方程其实就是一个简单的矩阵行列式。…

006 高并发内存池_PageCache设计

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;高并发内存池 &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言文章重点一、回顾PageCache页缓存结构二、PageCache结构设计三、完善申请内存函数小结 前言 本文将…

聊一聊电子邮件?

电子邮件是什么&#xff1f; 电子邮件是一种基于客户/服务器架构的应用。功能是实现人与人之间的交流。直到现在&#xff0c;电子邮件依然是当前因特网 注意&#xff1a;基于客户/服务器方式和基于B/S架构不一样&#xff01;客户/服务器表示的范围更广&#xff0c;当基于客户…

Linux环境jdk、git、maven、MySQL和redis的安装和配置

这里整理了在Linux上如何安装和配置jdk、git、maven、MySQL和redis&#xff0c;主要用于在Linux上部署Java项目 文章中博主使用了一个叫FinalShell远程连接软件进行上传&#xff0c;如果没有类似的工具也可以直接通过yum命令行下载包 博主使用的Linux服务器为centos7&#xf…

2024最新版Android studio安装入门教程(非常详细)

目录 JDK安装与配置 一、下载JDK 二、JDK安装 三、JDK的环境配置 四、JDK的配置验证 Android studio安装 Android studio连接手机真机调试&#xff08;以华为鸿蒙为例&#xff09; 一、新建一个android项目 二、进入项目面板 三、配置Android Studio 四、安装手机驱…

【JavaSE】初识线程,线程与进程的区别

文章目录 ✍线程是什么&#xff1f;✍线程和进程的区别✍线程的创建1.继承 Thread 类2.实现Runnable接口3.匿名内部类4.匿名内部类创建 Runnable ⼦类对象5.lambda 表达式创建 Runnable ⼦类对象 ✍线程是什么&#xff1f; ⼀个线程就是⼀个 “执行流”. 每个线程之间都可以按…

BigInteger的应用

这里写目录标题 例题BigInteger常用方法关于BigInteger初始化为nullcompareTo()方法 : 返回一个int型数据(1 大于; 0 等于 ; -1 小于) 例题 import java.math.BigInteger; import java.util.*; public class Main{public static void main(String[] args) {BigInteger n BigIn…

android 消息提醒

1.创建 MyBackgroundService.java 继承 Service public class MyBackgroundService extends Service {Overridepublic void onCreate() {super.onCreate();Log.i("业务服务", "开起业务服务");//调用服务后在页面手机上创建一个通知消息。if (android.os…

TS的基础

TS Typed JavaScript at Any Scale. 它强调了 TypeScript 的两个最重要的特性——类型系统、适用于任何规模。 我们知道&#xff0c;JavaScript 是一门非常灵活的编程语言&#xff0c; 它没有类型约束&#xff0c;一个变量可能初始化时是字符串&#xff0c;过一会儿又被赋值为…

如何用 C++ 在 10 行内写出八皇后?

在编程世界中&#xff0c;有时挑战在于以最简洁的方式表达复杂的逻辑。八皇后问题就是这样一道经典难题&#xff0c;它要求在88的棋盘上放置8个皇后&#xff0c;使得任意两个皇后之间都不能位于同一行、同一列或同一斜线上。虽然这个问题可以通过多种算法解决&#xff0c;包括递…

Scala介绍与环境搭建

Scala环境搭建与介绍 一、Scala环境搭建 1、环境准备与下载 2、验证Scala 3、IDEA新建项目&#xff0c;配置Scala&#xff0c;运行Hello world 二、Scala介绍 1、Scala 简介 2、Scala 概述 一、Scala环境搭建 1、环境准备与下载 JDK1.8 Java Downloads | Oracle 下载需求版本…

代码随想录|Day29|贪心04|860.柠檬水找零、406.根据身高重建队列、452.用最少数量的箭引爆气球

860.柠檬水找零 我们维护三种金额的数量&#xff1a;five&#xff0c;ten&#xff0c;twenty 有如下三种情况&#xff1a; 账单是5&#xff1a;five 1&#xff0c;无需找零账单是10&#xff1a;ten 1&#xff0c;找零一张5元&#xff08;five - 1&#xff09;账单是20&#x…

Eclipse EMF教程(上)

What every Eclipse developer should know about EMF 翻译自&#xff1a;https://eclipsesource.com/blogs/tutorials/emf-tutorial/ 本教程是对EMF的介绍&#xff0c;解释了EMF的基础知识。我们首先向您展示如何基于EMF构建一个非常简单的以数据为中心的应用程序&#xff0c…

MES_ENT_STD

生产执行系统&#xff08;企业标准版&#xff09;MES_ENT_STD ERP_ENT_STD_59438.ieqq.ent-CSDN博客 OAMS_ENT_STD-CSDN博客

分类预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积长短期记忆网络多输入分类预测

分类预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积长短期记忆网络多输入分类预测 目录 分类预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积长短期记忆网络多输入分类预测效果一览基本介绍模型搭建程序设计参考资料 效果一览 基本介绍 MATLAB实现BO-CNN-LSTM贝叶斯优化卷积长短期记…