模拟实现STL中list(用迭代器)
2018-03-14 23:17
591 查看
在上一篇博客中有很详细的介绍迭代器的用法。点击打开链接
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中增加元素也会导致迭代器失效,因为增加可能会导致增容,增容就要把上面的拷贝下来,再释放原来的,释放原来的就有可能导致迭代器失效。
总结:如果只访问数据用迭代器Iterator.
如果既要访问,又要修改用ConstIterator.
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 4000 = 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.
相关文章推荐
- 迭代器模拟实现STL中的list
- 【STL】迭代器与List的模拟实现
- STL容器中list与迭代器iterator的模拟实现
- 类模板模拟实现STL中List
- 模拟实现STL中的List容器
- 模拟实现STL中的list
- 模拟实现STL下的list容器
- C++模拟实现容器list(含迭代器)
- 模拟实现STL中的list
- 模拟实现STL中的list
- STL-模拟实现List
- 【STL】list的应用和模拟实现
- STL-模拟实现list
- STL模拟实现迭代器
- 数据结构::模拟STL实现list
- 模拟实现list(迭代器)
- 【C++】模拟实现STL中的list
- 模拟实现list(迭代器)
- 模拟实现容器List(迭代器)
- STL库中的list的使用和模拟实现