C++list类的模拟实现

一、list类的实现(放在my_list命名空间域中)

将整体的实现放在list.h头文件中

cpp 复制代码
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
namespace my_list
{
	//struct定义节点
	template<class T>
	struct list_node
	{
		list_node* _next;
		list_node* _prev;
		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;
		}
		//->重载
		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)const
		{
			return _node != it._node;
		}
	};

	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;
		//const迭代器如何设计呢?
		//typedef const_list_iterator<T> const_iterator;
		//不能像上面这样设计const迭代器,因为const迭代器是指向的内容不能修改,而不是本身不能修改
		//在operator*运算符重载处返回的T上加const九不能修改了

		//构造函数
		list()
		{
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		//析构函数
		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}
		//cear函数
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}
		//拷贝构造
		list(const list<T>& lt)
		{
			_head = new node;
			_head->_next = _head;
			_head->_prev = _head;

			for (auto& element : lt)
			{
				push_back(element);
			}

		}
		//迭代器
		iterator begin()
		{
			return _head->_next;//单参数的构造函数支持隐式类型转换
		}
		iterator end()
		{
			return _head;
		}
		//const迭代器
		const_iterator begin()const 
		{
			return const_iterator( _head->_next);//单参数的构造函数支持隐式类型转换
		}
		const_iterator end()const
		{
			return _head;
		}
		//push_back函数(也可以使用insert直接进行哨兵位的前面插入就是尾插)
		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函数(在pos位置之前插入)
		iterator insert(iterator pos, const T& x)
		{
			node* current = pos._node;
			node* prev = pos._node->_prev;
			node* newnode = new node(x);

			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = current;
			current->_prev = newnode;
			return newnode;
		}
		//erase函数
		iterator erase(iterator pos)
		{
			assert(pos != end());
			node* prev = pos._node->_prev;
			node* next = pos._node->_next;

			prev->_next = next;
			next->_prev = prev;

			delete pos._node;
			pos._node = nullptr;

			return next;
		}
		//pop_back尾删函数
		void pop_back()
		{
			erase(--end());
		}
		//push_front头插函数
		void push_front(const T& x)
		{
			insert(begin(), x);
		}
		//pop_front头删函数
		void pop_front()
		{
			erase(begin());
		}
		//size函数
		size_t size()
		{
			size_t sz = 0;
			iterator it = begin();
			while (it != end())
			{
				++it;
				++sz;
			}
			return sz;
		}
		//赋值重载
		void swap(list<T>& lt)
		{
			std::swap(_head, lt->_head);
		}
		list<T>& operator=(list<T> lt1)
		{
			swap(lt1);
			return *this;
		}
	private:
		node* _head;
	};
}

注意:const迭代器和普通迭代器使用两个模板参数就可以完成

二、对模拟实现的list进行测试

cpp 复制代码
#include "list.h"
//const迭代器测试
void print(const my_list::list<int> lt)
{
	my_list::list<int>::const_iterator it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << endl;
		++it;
	}
}
void test_my_list1()
{
	//尾插数据
	my_list::list<int> lt1;
	lt1.push_back(10);
	lt1.push_back(8);
	lt1.push_back(35);
	lt1.push_back(23);
	lt1.push_back(4346);

	//迭代器遍历
	my_list::list<int>::iterator it = lt1.begin();
	while (it != lt1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//范围for
	for (auto element : lt1)
	{
		cout << element << " ";
	}
	cout << endl;
	print(lt1);
}
struct A
{
public:
	A(int a = 0, int b = 0)
		:_a(a)
		,_b(b)
	{ }
	int _a;
	int _b;
};
void test_my_list2()
{
	//尾插数据
	my_list::list<A> lt1;
	lt1.push_back(A(1,1));
	lt1.push_back(A(2,2));
	lt1.push_back(A(3,3));
	//测试->重载
	my_list::list<A>::iterator it = lt1.begin();
	while (it != lt1.end())
	{
		cout << (*it)._a << (*it)._b << endl;
		cout << it->_a << it->_b << endl;
		//这里按照语法严格来说是it->->_a,但是由于运算符重载要求可读性,编译器做了特殊处理,省略了一个->
		++it;
	}
	cout << endl;
}
void test_my_list3()
{
	//尾插数据
	my_list::list<int> lt1;
	lt1.push_back(10);
	lt1.push_back(8);
	lt1.push_back(35);
	lt1.push_back(23);
	lt1.push_back(4346);

	//头插数据
	lt1.push_front(1);
	lt1.push_front(2);
	lt1.push_front(3);
	lt1.push_front(4);

	//打印
	for (auto element : lt1)
	{
		cout << element << " ";
	}
	cout << endl;

	//头删一个,尾删两个
	lt1.pop_front();
	lt1.pop_back();
	lt1.pop_back();
	//打印
	for (auto element : lt1)
	{
		cout << element << " ";
	}
	cout << endl;

	//清除重新插入数据
	lt1.clear();
	lt1.push_front(1);
	lt1.push_front(2);
	lt1.push_front(3);
	lt1.push_front(4);

	//打印
	for (auto element : lt1)
	{
		cout << element << " ";
	}
	cout << endl;
}
void test_my_list4()
{
	//拷贝构造测试
	my_list::list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);
	lt1.push_back(4);
	lt1.push_back(5);
	my_list::list<int> lt2(lt1);
	//打印lt2
	for (auto element : lt2)
	{
		cout << element << " ";
	}
	cout << endl;
	//赋值重载测试
	my_list::list<int> lt3 = lt1;
	for (auto element : lt3)
	{
		cout << element << " ";
	}
	cout << endl;
}
int main()
{
	test_my_list1();
	test_my_list2();
	test_my_list3();
	test_my_list4();
	return 0;
}

三、vector和list对比

相关推荐
“愿你如星辰如月”20 小时前
Linux:进程间通信
linux·运维·服务器·c++·操作系统
10岁的博客20 小时前
二维差分算法高效解靶场问题
java·服务器·算法
R-G-B20 小时前
归并排序 (BM20 数组中的逆序对)
数据结构·算法·排序算法
少许极端20 小时前
算法奇妙屋(十二)-优先级队列(堆)
数据结构·算法·leetcode·优先级队列··图解算法
lwhdjbcjdjd21 小时前
Nginx与Tomcat协作处理流程及数据流向
运维·nginx·tomcat
CIb0la21 小时前
安卓16系统升级后(Google pixel 8/8pro 9/9pro xl 10/10pro xl)救砖及Root方法
android·运维·生活
灵晔君21 小时前
C++标准模板库(STL)——list的模拟实现
c++·list
qq_3168377521 小时前
华为CCE k8s 使用nfs-subdir-external-provisioner 创建pvc时自动创建pv
windows·华为·kubernetes
kupeThinkPoem21 小时前
哈希表有哪些算法?
数据结构·算法
呉師傅1 天前
国产化操作系统---银河麒麟安装步骤(简单介绍)
运维·网络·windows·单片机·电脑