C++入门:STL_容器_list的模拟实现

list

本质是一个带有头结点的双向循环链表
头结点的下一个节点是第一个节点,头结点是尾节点
在这里插入图片描述

代码

#include <iostream>
using namespace std;

namespace bite
{
	// List的节点类
	template<class T>
	struct ListNode
	{
		ListNode(const T& val = T()) 
			:_pPre(nullptr)
			, _pNext(nullptr)
			, _val(val)
		{}//ListNode构造函数
		ListNode<T>* _pPre;
		ListNode<T>* _pNext;
		T _val;//类成员,前驱节点,后继节点和val值
	};

	template<class T>
	class list;

	//List的迭代器类
	template<class T, class Ref, class Ptr>
	class ListIterator
	{
		friend class list < T > ;
		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 &(operator*());
		}//重载->,访问其所指空间成员
		Self& operator++()
		{
			_pNode = _pNode->_pNext;
			return *this;
		}//重载前++
		Self operator++(int)
		{
			Self temp(*this);
			_pNode = _pNode->_pNext;
			return temp;
		}//重载后++
		Self& operator--()
		{
			_pNode = _pNode->_pPre;
			return *this;
		}//重载前--
		Self operator--(int)
		{
			Self temp(*this);
			_pNode = _pNode-> + pPre;
			return temp;
		}//重载后--
		bool operator!=(const Self& l)
		{
			return _pNode != l._pNode;
		}//重载!=
		bool operator==(const Self& l)
		{
			return _pNode == l._pNode;
		}//重载==
	private:
		PNode _pNode;//迭代器内部其实是一个指针,迭代器通过对这个指针的操作,来实现各种功能
		//这里解释一下为什么要有迭代器?
		//迭代器一般有两种实现方式,具体根据容器底层数据结构实现:
		//1.原生态指针,比如:vector
		//2.将原生态指针进行封装,在自定义的类中实现指针的功能,类似解引用,->,++,--,比较等。
		//比如:list这里就是将原生态指针进行了封装,因为单纯的指针没有办法实现链表的功能。
		//因为链表的++时指向下一个节点,而指针的++则是单纯的++,并不能指向链表的下一个节点。
		//注意:这里比较难理解,可以多看几遍。
	};


	//list类
	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;
	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();
			list<T> temp(l.begin(), l.end());
			this->swap(temp);
		}
		//赋值构造函数
		list<T>& operator=(list<T> l)
		{
			this->swap(l);
			return *this;
		}
		//赋值构造函数
		~list()
		{
			clear();
			delete _pHead;
			_pHead = nullptr;
		}
		///
		// List Iterator
		iterator begin(){ return iterator(_pHead->_pNext); }
		//返回第一个节点,也就是头结点的next
		iterator end(){ return iterator(_pHead); }
		//返回尾结点,即头结点
		const_iterator begin()const{return const_iterator(_pHead->_pNext);}
		const_iterator end()const{ return const_iterator(_pHead); }
		///
		// List Capacity
		//计算节点个数
		size_t size()const
		{
			iterator first=iterator(begin());
			iterator last = iterator(end());
			int count = 0;
			while (first != last)
			{
				count++;
				first++;
			}
			return count;
		}
		//判空
		bool empty()const{ return size() == 0; }
		
		// List Access
		//返回第一个节点的值
		T& front(){ return *begin(); }
		const T& front()const{ return *begin();}
		//返回最后一个节点的值
		T& back(){ return *--end(); }
		const T& back()const{ return *--end(); }
		
		// 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的节点,返回插入节点的指针
		iterator insert(iterator pos, const T& val)
		{
			PNode _S = new Node(val);
			PNode cur = pos._pNode;
			_S->_pPre = cur->_pPre;
			_S->_pNext = cur;
			_S->_pPre->_pNext = _S;
			cur->_pPre = _S;
			return iterator(_S);
		}
		// 删除pos位置的节点,返回该节点的下一个位置
		iterator erase(iterator pos)
		{
			PNode pDel = pos._pNode;
			PNode pRet = pDel->_pNext;

			pDel->_pNext->_pPre = pDel->_pPre;
			pDel->_pPre->_pNext = pRet;
			delete pDel;

			return iterator(pRet);
		}
		//按照数组来清除
		iterator erase(iterator _first, iterator _last)
		{
			while (_first != _last)
			{
				_first = erase(_first);
			}
			return iterator(_last);
		}
		//清空链表
		void clear()
		{
			erase(begin(), end());
		}
		//交换函数
		void swap(list<T>& l)
		{
			PNode tmp = new Node;
			tmp = _pHead;
			_pHead = l._pHead;
			l._pHead = tmp;
		}
	private:
	    //生成头结点
		void CreateHead()
		{
			_pHead = new Node;
			_pHead->_pNext = _pHead;
			_pHead->_pPre = _pHead;
		}
		//类成员,是一个头结点
		PNode _pHead;
	};
};

void main()
{
	bite::list<int> l1;
	bite::list<int> l2(10, 5);
	l2.push_back(2);
	l2.pop_back();
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	bite::list<int> l3(arr, arr + 10);
	auto pos = l3.begin();
	l3.insert(pos, 0);
	++pos;
	l3.insert(pos, 100);
	l3.erase(l3.begin());
	l3.erase(pos);
	bite::list<int> l4(l3);
	
	l1 = l4;
	l3.push_front(0);
	l3.pop_front();
	for (auto &e : l3)
		cout << e << " ";
	cout << endl;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值