您的位置:首页 > 其它

模拟实现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中增加元素也会导致迭代器失效,因为增加可能会导致增容,增容就要把上面的拷贝下来,再释放原来的,释放原来的就有可能导致迭代器失效。
#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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: