STL模拟实现List+迭代器

List的底层数据结构的实现就是双向循环链表,下面给出结点的封装,简易迭代器的封装,还有头指针的封装和相关功能的实现和测试的结果

1.结点的封装代码如下:

template<class T>
struct ListNode//定义结点的类
{
public:
	ListNode<T> *_pre;//后指针
	ListNode<T> *_next;//前指针
	T _data;//储存数据
public:
	ListNode(const T& data = T())//构造函数
		:_pre(0)
		, _next(0)
		, _data(data){}
};

2.给出简易迭代器的封装代码。其实迭代器就是一个可以指向结点的指针

template<class T,class Ref,class Src>//迭代器的类
class Iterator
{
public:
	ListNode<T>* _pCur;
public:
	Iterator()//构造函数
		: _pCur(0){}
	Iterator(ListNode<T>* pCur)//有参数的构造函数
		:_pCur(pCur){}
	Iterator(const Iterator<T,Ref,Src>& s)//拷贝构造函数
		:_pCur(s._pCur){}
	Ref& operator*()
	{
		return _pCur->_data;
	}
	Src* operator->()
	{
		return &(_pCur->_data);
	}
	Iterator < T, Ref, Src > operator++(int)//后置++
	{
		Iterator<T, Ref, Src> temp(*this);
		_pCur = _pCur->_next;
		return temp;
	}
	Iterator < T, Ref, Src > operator++()//前置++
	{
		_pCur = _pCur->_next;
		return *this;
	}
	Iterator < T, Ref, Src > operator--()//前置--
	{
		_pCur = _pCur->_pre;
		return *this;
	}
	Iterator < T, Ref, Src > operator--(int)//后置--
	{
		Iterator < T, Ref, Src > temp(*this)
		_pCur = _pCur->_pre;
		return temp;
	}
	bool operator!=(const Iterator < T, Ref, Src >& s)
	{
		return _pCur != s._pCur;
	}
	bool operator==(const Iterator < T, Ref, Src >& s)
	{
		return _pCur == s->_pPcur;
	}
	
};
因为迭代器其实就是指向结点的指针,既然是指针所以其对象就要有指针的相关功能,所以给出了上述的运算符重载函数

3.下面给出头指针的封装和具体的迭代器和结点的结合使用,还有相关的功能的实现

//可以直接在里面使用迭代器
template<class T>
class ListHead//封装头指针的类
{
public:
	ListNode<T> *_head;//定义头指针成员变量,指向结点的指针
	typedef Iterator<T, T&, T*> Iterator;//在这个类中定义迭代器
public:
	ListHead()//无参构造函数
		:_head(new ListNode<T>)//给头结点开辟空间
	{
		_head->_pre = _head;
		_head->_next = _head;
	}
	ListHead(const T*array, size_t size)//有参数的构造函数
		:_head(new ListNode<T>)//开辟头结点
	{
		_head->_next = _head;
		_head->_pre = _head;
		for (size_t i =0 ; i < size; i++)
		{
			PushBack(array[i]);
		}
	}
	/*List(const List& l);
	List& operator=(const List& l);*/
	~ListHead()
	{
		Clear();
		delete []_head;
		_head = NULL;
	}

	void PushBack(const T& data)
	{
		ListNode<T> *NewNode = new ListNode<T>(data);
		if (Empty())
		{
			_head->_next = NewNode;
			NewNode->_next = _head;
			NewNode->_pre = _head;
			_head->_pre = NewNode;
		}
		else
		{
			ListNode<T>* pLast = _head->_pre;//找到最后一个结点
			NewNode->_next = _head;
			NewNode->_pre = pLast;
			pLast->_next = NewNode;
			_head->_pre = NewNode;
		}
	}
	void PushFront(const T& data)
	{
		ListNode<T> *NewNode = new ListNode<T>(data);
		if (Empty())
		{
			_head->_next = NewNode;//头指针指向第一个结点
			NewNode->_next = _head;//第一个结点next指向头指针
			NewNode->_pre = _head;//第一个结点pre向头指针
			_head->_pre = NewNode;//头指针pre指向第一个结点
		}
		else
		{
			NewNode->_next = _head->_next;
			NewNode->_pre = _head;
			_head->_next->_pre = NewNode;
			_head->_next = NewNode;
		}
	}
	void PopFront()//头删除
	{
		if (!Empty())
		{
			ListNode<T> *p = _head->_next;//保存第一个结点
			_head->_next = p->_next;
			p->_next->_pre = _head;
			delet p;
		}
	}
	void PopBack()//尾删除
	{
		if (!Empty())
		{
			ListNode<T> *p = _head->_pre->_pre;//保存倒数第二个结点
			delete p->_next;//销毁最后一个结点
			p->_next = _head;
			_head->_pre = p;
		}
	}
	Iterator Begin()//返回第一个结点的地址
	{
		return  Iterator(_head->_next);
	}
	Iterator End()//返回最后一个结点的地址
	{
		return  Iterator(_head->_pre);
	}
	Iterator Insert(Iterator pos, const T& data)//指定位置插入,返回插入的结点
	{
		ListNode<T>* pNewNode = new ListNode<T>(data);
		pNewNode->_next = pos._pCur;
		pos._pCur->_pre->_next = pNewNode;
		pNewNode->_pre = pos._pCur->_pre;
		pos._pCur->_pre = pNewNode;
		return Iterator(pNewNode);
	}
	Iterator Erase(Iterator pos)//指定位置删除,返回删除的下一个结点
	{
		ListNode<T> *src = pos._pCur->_next;
		pos._pCur->_pre->_next = pos._pCur->_next;
		pos._pCur->_next->_pre = pos._pCur->_pre;
		delete pos._pCur;
		pos._pCur = NULL;
		return src;
	}
		bool Empty()const
		{
			return _head->_pre == _head;//只有一个头结点
		}
		size_t Size()const
		{
			ListNode<T> *dest = _head->_next;//标记第一个结点
			size_t count = 0;
			while (dest!= _head)
			{
				dest = dest->_next;
				count++;
			}
			return count;
		}
		T& Front()
		{
			return _head->_next->data;
		}
		const T& Front()const
		{
			return _head->_next->data;
		}
		T& Back()
		{
			return _head->_pre->data;
		}
		const T& Back()const
		{
			return _head->_pre->data;
		}
		void Clear()
		{
			Iterator it = Begin();//得到第一个结点的地址
			while (it != End())
			{
				it=Erase(it);
			}
			_head->_next = _head;
			_head->_pre = _head;
		}
	template<class Iterator, class T>
	Iterator Find(Iterator first, Iterator last, const T& data)
		{
			while (first != last)
			{
				if (*first == data)
					return first;

				++first;
			}
		}
};

下面是我的测试代码和结果,你可以根据自己的想法去测试

void TestList()
{
	int arr[] = { 1, 2, 3, 4, 5 };
	ListHead<int> s(arr, sizeof(arr) / sizeof(*arr));

	s.PushBack(6);
	s.PushFront(0);
	ListHead<int>::Iterator it = s.Begin();
	while (it != s.End())
	{
		cout << *it << "->";
		++it;
	}
	cout << *it;
	cout << "->NULL" << endl;

	cout << "Size()="<<s.Size() << endl;

	ListHead<int>::Iterator s1 = s.Find(s.Begin(), s.End(), 2);
	cout <<"s1=" <<*s1 << endl;

	ListHead<int>::Iterator s2 = s.Insert(s.Begin(), 100);
	ListHead<int>::Iterator it1 = s.Begin();
	while (it1 != s.End())
	{
		cout << *it1 << "->";
		++it1;
	}
	cout << *it1;
	cout << "->NULL" << endl;
}

下面给出整个项目的完整代码,

template<class T>
struct ListNode//定义结点的类
{
public:
	ListNode<T> *_pre;//后指针
	ListNode<T> *_next;//前指针
	T _data;//储存数据
public:
	ListNode(const T& data = T())//构造函数
		:_pre(0)
		, _next(0)
		, _data(data){}
};
template<class T,class Ref,class Src>//迭代器的类
class Iterator
{
public:
	ListNode<T>* _pCur;
public:
	Iterator()//构造函数
		: _pCur(0){}
	Iterator(ListNode<T>* pCur)//有参数的构造函数
		:_pCur(pCur){}
	Iterator(const Iterator<T,Ref,Src>& s)//拷贝构造函数
		:_pCur(s._pCur){}
	Ref& operator*()
	{
		return _pCur->_data;
	}
	Src* operator->()
	{
		return &(_pCur->_data);
	}
	Iterator < T, Ref, Src > operator++(int)//后置++
	{
		Iterator<T, Ref, Src> temp(*this);
		_pCur = _pCur->_next;
		return temp;
	}
	Iterator < T, Ref, Src > operator++()//前置++
	{
		_pCur = _pCur->_next;
		return *this;
	}
	Iterator < T, Ref, Src > operator--()//前置--
	{
		_pCur = _pCur->_pre;
		return *this;
	}
	Iterator < T, Ref, Src > operator--(int)//后置--
	{
		Iterator < T, Ref, Src > temp(*this)
		_pCur = _pCur->_pre;
		return temp;
	}
	bool operator!=(const Iterator < T, Ref, Src >& s)
	{
		return _pCur != s._pCur;
	}
	bool operator==(const Iterator < T, Ref, Src >& s)
	{
		return _pCur == s->_pPcur;
	}
	
};
//可以直接在里面使用迭代器
template<class T>
class ListHead//封装头指针的类
{
public:
	ListNode<T> *_head;//定义头指针成员变量,指向结点的指针
	typedef Iterator<T, T&, T*> Iterator;//在这个类中定义迭代器
public:
	ListHead()//无参构造函数
		:_head(new ListNode<T>)//给头结点开辟空间
	{
		_head->_pre = _head;
		_head->_next = _head;
	}
	ListHead(const T*array, size_t size)//有参数的构造函数
		:_head(new ListNode<T>)//开辟头结点
	{
		_head->_next = _head;
		_head->_pre = _head;
		for (size_t i =0 ; i < size; i++)
		{
			PushBack(array[i]);
		}
	}
	/*List(const List& l);
	List& operator=(const List& l);*/
	~ListHead()
	{
		Clear();
		delete []_head;
		_head = NULL;
	}

	void PushBack(const T& data)
	{
		ListNode<T> *NewNode = new ListNode<T>(data);
		if (Empty())
		{
			_head->_next = NewNode;
			NewNode->_next = _head;
			NewNode->_pre = _head;
			_head->_pre = NewNode;
		}
		else
		{
			ListNode<T>* pLast = _head->_pre;//找到最后一个结点
			NewNode->_next = _head;
			NewNode->_pre = pLast;
			pLast->_next = NewNode;
			_head->_pre = NewNode;
		}
	}
	void PushFront(const T& data)
	{
		ListNode<T> *NewNode = new ListNode<T>(data);
		if (Empty())
		{
			_head->_next = NewNode;//头指针指向第一个结点
			NewNode->_next = _head;//第一个结点next指向头指针
			NewNode->_pre = _head;//第一个结点pre向头指针
			_head->_pre = NewNode;//头指针pre指向第一个结点
		}
		else
		{
			NewNode->_next = _head->_next;
			NewNode->_pre = _head;
			_head->_next->_pre = NewNode;
			_head->_next = NewNode;
		}
	}
	void PopFront()//头删除
	{
		if (!Empty())
		{
			ListNode<T> *p = _head->_next;//保存第一个结点
			_head->_next = p->_next;
			p->_next->_pre = _head;
			delet p;
		}
	}
	void PopBack()//尾删除
	{
		if (!Empty())
		{
			ListNode<T> *p = _head->_pre->_pre;//保存倒数第二个结点
			delete p->_next;//销毁最后一个结点
			p->_next = _head;
			_head->_pre = p;
		}
	}
	Iterator Begin()//返回第一个结点的地址
	{
		return  Iterator(_head->_next);
	}
	Iterator End()//返回最后一个结点的地址
	{
		return  Iterator(_head->_pre);
	}
	Iterator Insert(Iterator pos, const T& data)//指定位置插入,返回插入的结点
	{
		ListNode<T>* pNewNode = new ListNode<T>(data);
		pNewNode->_next = pos._pCur;
		pos._pCur->_pre->_next = pNewNode;
		pNewNode->_pre = pos._pCur->_pre;
		pos._pCur->_pre = pNewNode;
		return Iterator(pNewNode);
	}
	Iterator Erase(Iterator pos)//指定位置删除,返回删除的下一个结点
	{
		ListNode<T> *src = pos._pCur->_next;
		pos._pCur->_pre->_next = pos._pCur->_next;
		pos._pCur->_next->_pre = pos._pCur->_pre;
		delete pos._pCur;
		pos._pCur = NULL;
		return src;
	}
		bool Empty()const
		{
			return _head->_pre == _head;//只有一个头结点
		}
		size_t Size()const
		{
			ListNode<T> *dest = _head->_next;//标记第一个结点
			size_t count = 0;
			while (dest!= _head)
			{
				dest = dest->_next;
				count++;
			}
			return count;
		}
		T& Front()
		{
			return _head->_next->data;
		}
		const T& Front()const
		{
			return _head->_next->data;
		}
		T& Back()
		{
			return _head->_pre->data;
		}
		const T& Back()const
		{
			return _head->_pre->data;
		}
		void Clear()
		{
			Iterator it = Begin();//得到第一个结点的地址
			while (it != End())
			{
				it=Erase(it);
			}
			_head->_next = _head;
			_head->_pre = _head;
		}
	template<class Iterator, class T>
	Iterator Find(Iterator first, Iterator last, const T& data)
		{
			while (first != last)
			{
				if (*first == data)
					return first;

				++first;
			}
		}
};


void TestList()
{
	int arr[] = { 1, 2, 3, 4, 5 };
	ListHead<int> s(arr, sizeof(arr) / sizeof(*arr));

	s.PushBack(6);
	s.PushFront(0);
	ListHead<int>::Iterator it = s.Begin();
	while (it != s.End())
	{
		cout << *it << "->";
		++it;
	}
	cout << *it;
	cout << "->NULL" << endl;

	cout << "Size()="<<s.Size() << endl;

	ListHead<int>::Iterator s1 = s.Find(s.Begin(), s.End(), 2);
	cout <<"s1=" <<*s1 << endl;

	ListHead<int>::Iterator s2 = s.Insert(s.Begin(), 100);
	ListHead<int>::Iterator it1 = s.Begin();
	while (it1 != s.End())
	{
		cout << *it1 << "->";
		++it1;
	}
	cout << *it1;
	cout << "->NULL" << endl;
}
只需要加上头文件和主函数就可以正常运行测试了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值