STL中的List

以下的List的模拟实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <assert.h>
#include <stdlib.h>
using namespace std;

//模拟实现list
//STL中的list是带头的、双向循环链表
//链表中的迭代器是被封装起来的指向结点的指针类,
//并且这个指针重载了自己的一些运算符,使得在链表中
//的++,*等操作挥应自如。//在实现普通迭代器、const迭代器过程中,
//我们像库中所做的一样,并没有分开实现两个类,而在再模板参数中做了手脚
//使得我们传参时自动实例化迭代器的类型(const与非const的普通类型)。

//链表结点结构(注意模板针对的是结点中元素的类型)
template<class T>
struct _ListNode
{
	T _data;
	_ListNode<T>* _prev;
	_ListNode<T>* _next;

	//构造函数(构造一个节点)
	_ListNode(const T& x)
		:_data(x)
		, _prev(nullptr)
		, _next(nullptr)
	{}
};

//迭代器结构(类)
//第一个模板参数是链表结点数据类型
//第二个模板参数是链表结点数据类型的引用(const与非const)
//第三个模板参数是指向链表结点的指针(const与非const)
template<class T, class Ref, class Ptr>
struct _ListIterator
{
	//链表结点类型重定义
	typedef _ListNode<T> Node;

	//迭代器类型重定义
	typedef _ListIterator<T, Ref, Ptr> self;

	//迭代器的成员变量就是一个结点指针
	Node* _node;

	//构造函数(用一个结点的指针构造一个迭代器)
	_ListIterator(Node* node)
		:_node(node)
	{}

	//重载前置加加
	self& operator++()
	{
		_node = _node->_next;
		return *this;
	}
	//重载后置加加
	self operator++(int)
	{
		_ListIterator tmp(*this);
		_node = _node->_next;
		return tmp;
	}

	//重载前置减减
	self& operator--()
	{
		_node = _node->_prev;
		return *this;
	}
	//重载后置减减
	self operator--(int)
	{
		_ListIterator tmp(*this);
		_node = _node->_prev;
		return tmp;
	}

	//重载!=
	bool operator!=(const self& s)
	{
		return _node != s._node;
	}

	//重载==
	bool operator!=(const self& s)
	{
		return _node == s._node;
	}

	//重载*
	Ref operator*()
	{
		return _node->_data;
	}

	//重载->
	Ptr operator->()
	{
		return &(operator*());
	}

	//不用自己实现拷贝构造、赋值运算符重载,因为
	//库里的是"浅拷贝",而这里我们需要的迭代器的
	//拷贝就是要浅拷贝

	//析构函数我们也不需要自己实现,因为迭代器指向的
	//是链表的结点,而链表的结点生命周期应该随链表
	//迭代器只是遍历一下,不管释放工作

};

//List正式开始
template<class T>
class List
{
public:
	typedef _ListNode<T> Node;//结点结构重命名

	//普通迭代器,const迭代器重命名
	typedef _ListIterator<T, T*, T&> iterator;
	typedef _ListIterator<T, const T*, const T&> const_iterator;

	//begin()、end()
	iterator begin()
	{
		//用第一个结点的指针构造指向第一个结点的迭代器
		return iterator(_head->_next);
	}
	iterator end()
	{
		return iterator(_head);
	}
	//const_begin()、const_end()
	const_iterator begin()const
	{
		//用第一个结点的指针构造指向第一个结点的迭代器
		return iterator(_head->_next);
	}
	const_iterator end()const
	{
		return iterator(_head);
	}

	//构造函数
	List()
	{
		//创建头结点
		_head = new Node;
	}

	//清理有效数据结点
	void clear()
	{
		Node* cur = _head->_next;
		while (cur != _head)
		{
			Node* next = cur->_next;
			delete cur;
			cur = next;
		}
		//重置头结点
		_head->_next = _head;
		_head->_prev = _head;
	}

	//析构函数
	~List()
	{
		//先清理有效数据结点
		clear();
		//再清理头结点
		delete _head;
		_head = nullptr;
	}

	size_t size()
	{
		size_t size = 0;
		for (const auto& e : *this)
		{
			++size;
		}
		return size;
	}

	bool empty()
	{
		return _head->_next == _head;
	}

	//拷贝构造函数
	List(List<T>& list)
	{
		//先创建头结点
		_head = new Node;
		_head->_next = _head;
		_head->_prev = _head;

		//再尾插有效数据结点
		const_iterator it = list.begin();
		while (it != list.end())
		{
			push_back(*it);
			++it;
		}
	}

	//赋值运算符重载
	List<T>& operator=(List<T> list)
	{
		swap(_head, list._head);
		return *this;
	}

	//在pos位置前插入一个数据(pos传的是指针)
	void insert(iterator pos, const T& x)
	{
		Node* cur = pos._node;//先拿到pos的指针(pos是迭代器)
		Node* prev = cur->_prev;

		Node* newnode = new Node(x);

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

	//尾插
	void push_back(const T& x)
	{
		//复用insert
		insert(end(), x);
	}

	//头插
	void push_front(const T& x)
	{
		//复用insert
		insert(begin(), x);
	}

	//删除pos位置结点(pos传迭代器)
	//返回下一个结点的迭代器
	iterator erase(iterator pos)
	{
		Node* cur = pos._node;
		Node* prev = cur->_prev;
		Node* next = cur->_next;

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

		return iterator(next);
	}

	//尾删
	void pop_back()
	{
		//复用erase
		erase(--end());
	}

	//头删
	void pop_front()
	{
		//复用erase
		erase(begin());
	}

private:
	Node * _head;
};

猜你喜欢

转载自blog.csdn.net/lyl194458/article/details/88747205