STL--List 常用接口模拟实现

STL--List 常用接口模拟实现:

  1. 1、list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。

  2. 2、list的底层是双向循环链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指

  3. 针指向其前一个元素和后一个元素。

1、常用接口介绍:

 1>构造:

  • list()------------------------------构造空的list
  • list(size_type n, const value_type& val = value_type())------构造的list中包含n个值为val的元素
  • list(const list& x)------------------拷贝构造函数
  • list(InputIterator first,InputerIterator last)----------用[first,last)区间中的元素构造list

       2、list iterator的使用:此处,大家可暂时将迭代器理解成一个指针,该指针指向list中的某个节点。

  • begin() + end()----(正向迭代器)---返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
  • rbegin() + rend()----(反向迭代器)---返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 reverse_iterator,即begin位置

       3、list  capacity

  • empty()----------------检测list是否为空,是返回true,否返回false
  • size()------------------返回list中有效节点的个数

      4、list element access

  • front()------------------返回list的第一个节点中值的引用
  • back()------------------返回list的最后一个节点中值的引用

      5、list  modifiers

  • push_front()------------------在list首元素前插入值为val的元素
  • pop_front()-------------------删除list中第一个元素
  • push_back()-------------------在list尾部插入值为val的元素
  • pop_back()-------------------删除list中最后一个元素
  • insert()-----------------------在list position 位置中插入值为val的元素
  • erase()-----------------------删除list position位置的元素
  • swap()----------------------交换两个list中的元素
  • clear()-----------------------清空list中的有效元素

2、迭代器失效问题:

此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节 点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代 器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

3、总结:

1、实现List,首先要搞清楚List的底层结构:带头节点的双向循环链表。

2、整个List的实现过程,精华部分在于迭代器的重新封装,而迭代器又分为正向迭代器和反向迭代器,反向迭代器实际上是利用了正向迭代器进行封装,所以要模拟实现List,一定要先搞懂List中正向迭代器的封装。

3、正确使用模版,让你的代码更高效。

4、代码实现:


//STL-List 模拟实现
#include<iostream>
using namespace std;

namespace lxy
{
	//list:带头节点的双向循环链表
	template<class T>
	struct ListNode   //创建一个节点
	{
		ListNode(const T& data = T())   
			:_pNext(nullptr)
			, _pPre(nullptr)
			, _data(data)
		{}

		ListNode<T>* _pNext;
		ListNode<T>* _pPre;
		T _data;
	};

	//list迭代器:将节点类型的指针重新封装
	template<class T>
	struct List_iterator
	{
		typedef ListNode<T> Node;      //给ListNode<T> 取别名为 Node,方便使用
		typedef List_iterator<T> Self;   //作用同上
	public:
		List_iterator(Node* pCur)
			:_pCur(pCur)
		{}

		//按照指针方式进行应用
		T& operator*()
		{
			return _pCur->_data;
		}

		T* operator->()
		{
			return &(_pCur->_data);
		}

		//移动
		Self& operator++()      //前置++
		{
			_pCur = _pCur->_pNext;
			return *this;
		}

		Self operator++(int)     //有参数的为后置++
		{
			Self temp(*this);
			_pCur = _pCur->_pNext;
			return temp;
		}

		Self& operator--()      //前置--
		{
			_pCur = _pCur->_pPre;
			return *this;
		}

		Self operator--(int)   //有参数的为后置--
		{
			Self temp(*this);
			_pCur = _pCur->_pPre;
			return temp;
		}

		//比较
		bool operator!=(const Self& s)
		{
			return _pCur != s._pCur;
		}
		bool operator==(const Self& s)
		{
			return _pCur == s._pCur;
		}

		Node* _pCur;
	};

	//反向迭代器封装
	template<class Iterator,class T>
	struct list_reverse_iterator
	{
		typedef list_reverse_iterator<Iterator, T> Self;
	public:
		list_reverse_iterator(Iterator it)
			:_it(it)
		{}

		//按照指针方式进行应用
		T& operator*()
		{
			Iterator temp = _it;
			--temp;
			return *temp;
		}

		T* operator->()
		{
			return &(Operator*());
		}

		//移动
		Self& operator++()
		{
			--_it;
			return *this;
		}

		Self& operator++(int)
		{
			Self temp (*this);
			_it--;
			return temp;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}

		Self& operator--(int)
		{
			Self temp(*this);
			_it++;
			return  temp;
		}

		//比较
		bool operator!=(const Self& s)
		{
			return _it != s._it;
		}

		bool operator==(const Self& s)
		{
			return _it != s._it;
		}

		Iterator _it;
	};

	template<class T>
	class list
	{
		typedef ListNode<T> Node;
	public:
		typedef List_iterator<T> iterator;
		typedef list_reverse_iterator<iterator, T> reverse_iterator;
	public:
		//四种构造方法,赋值运算符重载,析构
		//1、
		list()               //构造一个只含头节点的list
		{
			CreatHead();
		}

		//2、n个data
		list(int n, const T& data)  //这里int原本应该是size_t,但是使用区间构造时,会发生歧义,故改成int
		{
			CreatHead();
			for (size_t i = 0; i < n; ++i)
			{
				push_back(data);
			}
		}

		//3、区间构造
		template<class Iterator>
		list(Iterator first, Iterator last)
		{
			CreatHead();
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		//4、拷贝构造
		list(const list<T>& L)
		{
			CreatHead();
			Node* pCur = L._pHead->_pNext;
			while (pCur != L._pHead)  //循环遍历完一圈
			{
				push_back(pCur->_data);
				pCur = pCur->_pNext;
			}
		}

		//赋值运算符重载 ’=‘
		list<T>& operator=(const list<T>& L)
		{
			if (this != &L)     //确保不是自己给自己赋值
			{
				clear();    //把自己的元素先清空
				Node* pCur = L._pHead->_pNext;
				while (pCur != _pHead)
				{
					push_back(pCur->_data);
					pCur = pCur->_pNext;
				}
			}
			return *this;
		}

		//析构
		~list()
		{
			clear();   //清除所有元素
			delete _pHead;    //释放指针
		}

	public:
		//迭代器相关操作
		iterator begin()
		{
			return iterator(_pHead->_pNext);
		}

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

		reverse_iterator rbegin()
		{
			return end();
		}

		reverse_iterator rend()
		{
			return begin();
		}

	public:
		//容量相关操作
		size_t size()const
		{
			size_t count = 0;
			Node* pCur = _pHead->_pNext;
			while (pCur != _pHead)
			{
				++count;
				pCur = pCur->_pNext;
			}
			return count;
		}

		size_t empty()const
		{
			return _pHead->_pNext == _pHead;   //让头节点指向自己,则为空链表
		}

		void resize(size_t newsize, const T& data = T())
		{
			size_t oldsize = size();
			if (newsize > oldsize)   //判断节点是否需要增多
			{
				//节点增多
				for (size_t i=oldsize; i < newsize; ++i)
				{
					push_back(data);
				}
			}
			else
			{
				//节点减少
				for (size_t i = newsize; i < oldsize; ++i)
				{
					pop_back();
				}
			}
		}

	public:
		//元素访问
		T& front()
		{
			return _pHead->_pNext->_data;
		}

		const T&front()const
		{
			return _pHead->_pNext->_data;
		}

		T& back()
		{
			return _pHead->_pPre->_data;
		}

		const T& back()const
		{
			return _pHead->_pPre->_data;
		}

    public:
	    //Modify 修改
	   void push_back(const T& data)
	   {
		   insert(end(), data);
	   }

	   void pop_back()
	   {
		   erase(--end());  //顺时针转
	   }

	   void  push_front(const T& data)
	   {
		   insert(begin(), data);
	   }

	   void pop_front()
	   {
		   erase(begin());
	   }

	   iterator insert(iterator pos, const T& data)
	   {
		   Node* pNewNode = new Node(data);//创建新节点
		   Node* pCur = pos._pCur;

		   pNewNode->_pPre = pCur->_pPre;
		   pNewNode->_pNext = pCur;
		   pNewNode->_pPre->_pNext = pNewNode;
		   pNewNode->_pNext->_pPre = pNewNode;

		   return iterator(pNewNode);
	   }

	   iterator erase(iterator pos)
	   {
		   Node* pDelNode = pos._pCur;
		   if (pDelNode == _pHead)    //不能删头节点,所以需要判空
		   {
			   return end();
		   }

		   Node* pRet = pDelNode->_pNext;   
		   pDelNode->_pPre->_pNext = pDelNode->_pNext;
		   pDelNode->_pNext->_pPre = pDelNode->_pPre;
		   delete pDelNode;    //销毁删除节点,防止内存泄露

		   return iterator(pRet);
	   }

	   void  clear()
	   {
		   Node*pCur = _pHead->_pNext;
		   //头删法
		   //[]-->1-->2-->3...
		   while (pCur != _pHead)   //判空
		   {
			   _pHead->_pNext = pCur->_pNext;
			   delete pCur;
			   pCur = _pHead->_pNext;
		   }

		   _pHead = _pHead->_pNext ;    //形成只有头节点的空链表
		   _pHead = _pHead->_pPre ;
	   }

	   void swap(list<T>& L)
	   {
		   swap(_pHead,L._pHead)
	   }

   private:
	   //创建一个头节点
	   void CreatHead()
	   {
		   _pHead = new Node;
		   _pHead->_pNext = _pHead;
		   _pHead->_pPre = _pHead;
	   }
   protected:
	   Node* _pHead;
	};
}

//测试
#include<vector>
void TestList1()
{
	lxy::list<int> L1;
	lxy::list<int> L2(10, 5);

	vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	lxy::list<int> L3(v.begin(), v.end());
	lxy::list<int> L4(L3);

	auto it = L2.begin();
	while (it != L2.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	for (auto e : L3)
		cout << e << " ";
	cout << endl;

	auto rit = L4.rbegin();
	while (rit != L4.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}

void TestList2()
{
	lxy::list<int> L;
	L.push_back(1);
	L.push_back(2);
	L.push_back(3);
	L.push_back(4);

	cout << L.size() << endl;
	cout << L.front() << endl;
	cout << L.back() << endl;

	L.push_front(0);
	cout << L.size() << endl;
	cout << L.front() << endl;
	cout << L.back() << endl;

	L.pop_front();
	cout << L.size() << endl;
	cout << L.front() << endl;
	cout << L.back() << endl;

	L.pop_back();
	cout << L.size() << endl;
	cout << L.front() << endl;
	cout << L.back() << endl;

	L.clear();
	if (L.empty())
		cout << "clear is OK" << endl;
}

void TestList3()
{
	lxy::list<int> L;
	L.push_back(1);
	L.push_back(2);
	L.push_back(3);

	L.resize(10, 5);
	for (auto e : L)
		cout << e << " ";
	cout << endl;

	L.resize(2);
	for (auto e : L)
		cout << e << " ";
	cout << endl;

}

int main()
{
	//TestList1();
	//TestList2();
	TestList3();
    return 0;
}
发布了83 篇原创文章 · 获赞 26 · 访问量 8705

猜你喜欢

转载自blog.csdn.net/lexiaoyao_0000/article/details/102534738