STL学习——浅谈List类的模拟实现

       本文模拟实现了c++标准模板库中的List。 它的底层实现是一个带头结点的双向循环链表。
       一个注意要点是,不同于vector和string的迭代器的封装

typedef  T* Iterator

List 采用了一个类来封装迭代器

//list迭代器的封装
	template <class T, class Ref, class Ptr>
	struct ListIterator
	{
		typedef ListIterator <T, Ref, Ptr>  Self;
		ListNode<T>* _node;
		
		ListIterator(ListNode<T>* node)
			: _node(node)
		{}

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

		Ptr operator->()
		{
			return &(_node->_data);
		}

		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		Self operator++(int)
		{
			Self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		bool operator !=(const Self& lit)
		{
			return _node != lit._node;
		}

		bool operator==(const Self& lit)
		{
			return _node == lit._node;
		}
	};
	
	

然后在List类中进行typedef

template <class T>
class List
{
public:
			typedef ListNode<T> Node;
			typedef ListIterator<T, T&, T*> iterator;
			typedef const ListIterator<T, T&, T*> const_iterator;
			typedef Node* pNode;

OK,迭代器的实现在这里强调一下。剩下的都不难理解。
       

下面给出List的模拟实现:

//模拟实现STL---list :带头结点的循环双向链表

namespace tonglin{    //命名空间

	template <class T>
	struct ListNode
	{
		ListNode(const T& val = T())
		: _data(val)
		, _next(nullptr)
		, _prev(nullptr)
		{}

		T _data;
		ListNode<T>* _next;
		ListNode<T>* _prev;
	};

	//list迭代器的封装
	template <class T, class Ref, class Ptr>
	struct ListIterator
	{
		typedef ListIterator <T, Ref, Ptr>  Self;
		ListNode<T>* _node;
		
		ListIterator(ListNode<T>* node)
			: _node(node)
		{}

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

		Ptr operator->()
		{
			return &(_node->_data);
		}

		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		Self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		Self operator++(int)
		{
			Self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		bool operator !=(const Self& lit)
		{
			return _node != lit._node;
		}

		bool operator==(const Self& lit)
		{
			return _node == lit._node;
		}
	};
	
	

template <class T>
class List
{
public:
			typedef ListNode<T> Node;
			typedef ListIterator<T, T&, T*> iterator;
			typedef const ListIterator<T, T&, T*> const_iterator;
			typedef Node* pNode;

//List的构造函数
			List()
			{
				cout << "Constructor called!" << endl;
				_head = new Node;
				_head->_next = _head;
				_head->_prev = _head;
			}
	
//拷贝构造函数,要实现深拷贝
			List(const List& lst)
			{
				//先创建头节点
				_head = new Node;
				_head->_next = _head;
				_head->_prev = _head;

				//再将数据赋进去
				for (const auto &e : lst)
				{
					PushBack(e);
				}
			}

//析构函数
			~List()
			{
				cout << "destructor called!" << endl;
				Clear();
				if (_head)
				{
					delete _head;
					_head = nullptr;
				}
			}
	
			
//赋值运算符重载
			List<T>& operator=(const List<T> lst)
			{
				/*if (this != &lst)
				{
					_head = new Node;
					_head->_next = _head;
					_head->_prev = _head;
					for (const auto& e : lst)
					{
						PushBack(e);
					}
				}
				return *this;*/
				swap(_head, lst._head);
				return *this;

			}
			
///////////////////////////////
//////////华丽分割/////////////
///////////////////////////////

			iterator begin()
			{
				return iterator(_head->_next);
			}

			iterator end()
			{
				return iterator(_head);
			}

			const_iterator begin() const
			{
				return const_iterator(_head->_next);
			}

			const_iterator end() const
			{
				return const_iterator(_head);
			}

			

			//尾插
			void PushBack(const T& val)
			{
				pNode newNode = new Node(val);   //创建新节点 -》 prev和next赋值 -》(对有所影响的数据项做更改) 之前的最后一个节点的next更新为newnode -》head的prev更新
				newNode->_next = _head;
				newNode->_prev = _head->_prev;
				newNode->_prev->_next = newNode;
				_head->_prev = newNode;
			}

			//尾删
			void PopBack()
			{
				//先找到最后一个节点
				pNode pDel = _head->_prev;
				if (pDel != _head)
				{
					//如果不是空链表,那么就对删除后有影响的数据项做以修改
					pDel->_prev->_next = _head;
					_head->_prev = pDel->_prev;
					delete pDel;
				}
				else
					return;
			}

			//头插
			void PushFront(const T& val)
			{
				//若还没有有效节点,则就是尾插
				if (isEmpty())
				{
					PushBack(val);
				}
				else
				{
					pNode newNode = new Node(val);
					_head->_next->_prev = newNode;
					newNode->_next = _head->_next;
					_head->_next = newNode;
					newNode->_prev = _head;
				}
			}

			//头删
			void PopFront()
			{
				//若没有有效节点
				if (isEmpty())
				{
					cout << "删除失败!" << endl;
				}
				else
				{
					//找到要删除的节点
					pNode pDel = _head->_next;
					_head->_next = pDel->_next;
					pDel->_next->_prev = pDel->_prev;
					delete pDel;
				}
			}

			//在pos位置前插入节点
			void Insert(iterator pos, const T& val)
			{
				pNode newNode = new Node(val);
				pNode cur = pos._node;
				newNode->_prev = cur->_prev;
				newNode->_prev->_next = newNode;
				newNode->_next = cur;
				cur->_prev = newNode;
			}

			//删除pos位置的节点,返回该节点的下一个位置
			iterator Erase(iterator pos)
			{
				//不能删除头结点
				if (pos != end())
				{
					pNode cur = pos._node;
					cur->_prev->_next = cur->_next;
					cur->_next->_prev = cur->_prev;
					//更新迭代器
					pos = iterator(cur->_next);
					delete cur;
				}
				return pos;
			}




			void Clear()
			{
				//清空,即保留头节点,删除其他所有有效节点

				pNode cur = _head->_next;
				while (cur != _head)
				{
					_head->_next = cur->_next;
					delete cur;
					cur = _head->_next;
				}

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

			//获取节点个数
			size_t Size() const
			{
				size_t count = 0;
				pNode cur = _head->_next;
				while (cur != _head)
				{
					++count;
					cur = cur->_next;
				}
				return count;
			}


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

			void printList()
			{
				auto lit = this->begin();
				while (lit != this->end())
				{
					cout << *lit << " ";
					++lit;
				}
				cout << endl;
			}
			
			
private:
	pNode _head;



	};

}//end of namespace:tongin

猜你喜欢

转载自blog.csdn.net/tonglin12138/article/details/93041802