模拟实现STL中list(用迭代器)


在上一篇博客中有很详细的介绍迭 代器的用法。

STL中list底层其实是带头双向循环列表,STL中使用迭代器(iterator)指向list的结点,并进行增删查改等操作,本篇我们模拟STL中list的常用操作。

先来构造list中的结点

template<class T>
struct My_ListNode
{
	T _date;
	My_ListNode<T>* _next;
	My_ListNode<T>* _prev;
	My_ListNode(const T& x)//结点的构造
		:_next(NULL)
		, _prev(NULL)
		, _data(data)
	{}
};

底下直接上代码:
注意用迭代器实现的list,一定要避免迭代器失效    一般删除会导致迭代器失效,但是在vector中增加元素也会导致迭代器失
效,因为增加可能会导致增容,增容就要把上面的拷贝下来,再释放原来的,释放原来的就有可能导致迭代器失效。
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
template<class T>
struct My_ListNode
{
	My_ListNode(const T& x=T())//结点的构造
		:_next(NULL)
		, _prev(NULL) 
		, _data(x)
	{}
	
	T _data;
	My_ListNode<T>* _next;
	My_ListNode<T>* _prev;
};


template <class T,class Ref,class Ptr>
struct List_Iterator
{
    typedef My_ListNode<T>  Node;
	typedef List_Iterator<T,Ref,Ptr> self;
	
	List_Iterator(Node* node)
		:_node(node)
	{}
	T& operator *()
	{
		return _node->_data;
	}
    T* operator ->()//如果结构体返回AA*
	{
	return &(_node->_data);
	}
	self& operator++ ()
	{
		_node = _node->_next;
		return *this;
	}
	self operator++(int)
	{
		self tmp(*this);
		_node = _node->_next;
		return tmp;
	}
	self& operator-- ()
	{
		_node = _node->_prev;
		return *this;
	}
	self operator--(int)
	{
		self tmp(*this);
		_node = _node->_prev;
		return tmp;
	}
	bool operator!=(const self& s)const
	{
		return _node != s._node;
	}
	Node* _node;
};
template<class T>
class  List
{
public:
	typedef My_ListNode<T>  Node;
	typedef List_Iterator<T,T&,T*> Iterator;
	typedef List_Iterator< T,const T&,const T*> ConstIterator;
	List()
		:_head(new Node)
	{
		_head->_next = _head;
		_head->_prev = _head;
	}

	void PushBack(const T& x)
	{
		Node* NewNode = new Node(x);
		Node* Tail = _head->_prev;
		Tail->_next = NewNode;
		NewNode->_prev = Tail;
		_head->_prev = NewNode;
		NewNode->_next = _head;
	}
	void PushFront(const T&x)
	{
		Insert(End(), x);
	}
	void PopBack()
	{
		Erase(--End());//End是迭代器,支持++,--
	}
	void Insert(Iterator pos, const T& x)
	{
		Node* prev= pos._node->_prev;//注意此处不能写成pos->_prev,因为pos是迭代器,而非Node*结点指针
		Node* NewNode = new Node(x);
		Node*cur = pos._node;
		prev->_next = NewNode;
		NewNode->_prev = prev;
		NewNode->_next = cur;
		cur->_prev = NewNode;

			
	}
	//注意STL中的Erase是有返回值的,因为要解决迭代器失效问题
	Iterator Erase(Iterator pos)
	{
		assert(pos != End());//注意不能删掉头
		Node*next = pos._node->_next;
		Node* prev = pos._node->_prev;
		prev->_next = next;
		next->_prev = prev;
		delete pos._node;
		return Iterator(next);//有返回值,解决迭代器失效的问题  也可以是return next;隐式类型转换

	}
	Iterator Begin() 
	{
		return Iterator(_head->_next);
	}
	Iterator End()
	{
		return Iterator(_head);
	}
	ConstIterator Begin()const
	{
		return ConstIterator(_head->_next);
	}
	ConstIterator  End()const
	{
		return ConstIterator(_head);
	}
	
	Node* _head;
};
void PrintList(const List <int>&l1)
{
	List<int>::ConstIterator it1 = l1.Begin();//如果为参数为const,那就掉ConstIterator,如果参数为非const,那就掉Iterator
	while (it1 != l1.End())
	{
		//if (*it1 % 2)
		//{
		//*it1 = *it1 * 2;
		//}
		cout << *it1 << " ";
		++it1;
	}
}
void test()
{
	List<int> l1;
	l1.PushBack(1);
	l1.PushBack(2);
	l1.PushBack(3);
	l1.PushBack(4);
	l1.Insert(l1.Begin(), 0);
	l1.Erase(l1.Begin());
	l1.PushFront(5);
	l1.PopBack();
	PrintList(l1);
	struct AA
	{
		int _a;
		int _b;
	};
	//List<AA>l2;
	//l2.PushBack(AA());
	//l2.PushBack(AA());
	//List<AA>::Iterator it2 = l2.Begin();
	//cout << (*it2)._a << endl;
	//cout << it2->_a << endl;//其实是编译器的优化实际应为it2->->
}

总结:如果只访问数据用迭代器Iterator.

         如果既要访问,又要修改用ConstIterator.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值