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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章