您的位置:首页 > 其它

模拟实现STL中的list

2017-07-29 11:09 465 查看
在前面博客中我已介绍了STL中的list使用

list和vector是被经常使用的容器,相较于vector的连续线性空间,list就显得比较复杂,它的好处是每次

插入或释放一个元素,就配置或释放一个空间,因此list对空间的应用绝对的精准,而且对于任何位置的插入

和元素删除,list永远是常数时间。它是一个双向链表。

在模拟实现之前我们先研究一下迭代器失效问题

先研究一下看STL库中是怎么处理的。

void Printlist(list<int>&L)
{
list<int>::iterator it = L.begin();
while (it != L.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}

void Test1()
{
int arr[] = { 1, 2,4, 3, 4, 5, 6 };
list<int> L(arr, arr + 6);
list<int>::iterator it = L.begin();

while (it != L.end())
{
if (*it % 2 == 0)
L.erase(it);
++it;
}
Printlist(L);
}


如果像上边那样删除 结果程序挂了 因为我们在外面一删,就会导致迭代器找不到下一处地址,

这就是迭代器失效问题。

void Printlist(list<int>&L)
{
list<int>::iterator it = L.begin();
while (it != L.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}

void Test1()
{
int arr[] = { 1, 2, 4, 3, 4, 5, 6 };
list<int> L(arr, arr + 6);
list<int>::iterator it = L.begin();

while (it != L.end())
{
if (*it % 2 == 0)
it=L.erase(it);
else
++it;
}
Printlist(L);
}


这样就可以了 因为标准库里边删除是返回的下一处地址,我们在外面一接收这样就避免程序挂掉。

模拟实现代码:

//reverse.h反向迭代器
#pragma once
#include "list.h"
template<class Iterator>
//这里边的Iterator传的是正向迭代器实现了代码的复用
class ReverseIterator
{
public:
typedef ReverseIterator<Iterator> Self;
ReverseIterator(Iterator it)
:_current(it)
{}
typename Iterator::Reference& operator*()
{
Iterator It = _current;
return *(--It);
}
typename Iterator::Pointer operator->()
{
return &(operator*());
}
Self& operator++()
{
--_current;
return *this;
}
Self operator++(int)
{
Iterator It = _current;
--_current;
return It;
}
Self& operator--()
{
++_current;
return *this;
}
Self operator--(int)
{
Iterator It = _current;
++_current;
return It;
}
bool operator!=(const Self& s)
{
return _current != s._current;
}
protected:
Iterator _current;
};


#pragma once
#include"reverse.h"
template<class T>
struct ListNode  //链表节点
{
T _data;
ListNode<T>* _prev;
ListNode<T>* _next;
ListNode(const T& data)
:_data(data)
, _prev(NULL)
, _next(NULL)
{}
};

template<class T,class Ref,class Ptr>
struct __ListIterator //正向迭代器
{
typedef ListNode<T> Node;
typedef __ListIterator<T, Ref, Ptr> Self;
typedef Ref Reference;
typedef Ptr Pointer;
__ListIterator(Node* node)
:_node(node)
{}
Ref& operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(operator*());
}
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 *this;
}
bool operator!=(const Self& s)
{
return _node != s._node;
}

Node* _node;
};

template<class T>
class List
{
typedef ListNode<T> Node;
public:
typedef __ListIterator<T, T&, T*> Iterator;
typedef __ListIterator<T, const
e888
T&, const T*> ConstIterator;
typedef ReverseIterator<ConstIterator> ConstReverseIterator;
typedef ReverseIterator<Iterator> ReverseIterator;
Node* BuyNode(const T& data) //构造节点
{
return new Node(data);
}
List() //带头结点的双向链表
{
_head = BuyNode(T());
_head->_next = _head;
_head->_prev = _head;
}
void Clear()
{
Iterator It = Begin();
while (It!=End())
{
Node* del = It._node;
++It;
delete del;
}
//删除完记得把头结点前后连接起来
_head->_prev = _head;
_head->_next = _head;
}
~List()
{
Clear();
delete _head;
_head = NULL;
}
Iterator Begin()
{
return Iterator(_head->_next);
}
Iterator End()
{
return Iterator(_head);
}

ConstIterator Begin() const
{
return ConstIterator(_head->_next);
}
ConstIterator End() const
{
return ConstIterator(_head);
}

Iterator Find(const T& x)
{
Iterator it = Begin();
while (it != End())
{
if (*it == x)
return it;
++it;
}
return End();
}

void Insert(Iterator& pos, const T& data)
{
assert(pos._node);
Node* tmp = BuyNode(data);
Node* cur = pos._node;
Node* Prev = (pos._node)->_prev;

Prev->_next = tmp;
tmp->_prev = Prev;

tmp->_next = cur;
cur->_prev = tmp;
}

void PushBack(const T& data)
{
Insert(End(), data);
}
void PushFront(const T& data)
{
Insert(Begin(), data);
}
bool Empty()
{
return _head->_next == _head;
}
Iterator Erase(Iterator& pos)
{
assert(!Empty() && pos._node);
Node* Prev = (pos._node)->_prev;
Node* Next = (pos._node)->_next;

delete pos._node;

Prev->_next = Next;
Next->_prev = Prev;

pos=Prev;
return Next;
}
void PopBack()
{
Erase(--End());
}
void PopFront()
{
Erase(Begin());
}

ReverseIterator Rbegin()
{
return ReverseIterator(End());
}
ReverseIterator Rend()
{
return ReverseIterator(Begin());
}

ConstReverseIterator Rbegin() const
{
return ConstReverseIterator(End());
}
ConstReverseIterator Rend() const
{
return ConstReverseIterator(Begin());
}
template<class InputIterator>
void Assign(InputIterator first, InputIterator last)
{
Clear();
while (first != last)
{
PushBack(*first);
++first;
}
}
private:
Node* _head;
};

void PrintMyList(List<int>& L)
{
List<int>::Iterator it = L.Begin();
while (it != L.End())
{
cout << *it << " ";
++it;
}
cout << endl;
}

void PrintMyListRR(List<int>& L)
{
List<int>::ReverseIterator rit = L.Rbegin();
while (rit != L.Rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
}

void TestMylist()
{
List<int> L;
L.PushBack(1);
L.PushBack(2);
L.PushBack(3);
L.PushBack(4);
L.PushBack(5);
PrintMyList(L);
PrintMyListRR(L);
List<int> L1;
L1.Assign(L.Begin(), L.End());
PrintMyList(L1);
int arr[] = { 1, 2, 3, 4, 5 };
List<int> L2;
L2.Assign(arr, arr + 5);
PrintMyList(L2);
//List<int>::Iterator it = L.Begin();
/*while (it != L.End())
{
if (*it % 2 == 0)
{
it = L.Erase(it);
}
else
++it;
}
*/
/*while (it != L.End())
{
if (*it % 2 == 0)
L.Erase(it);
++it;
}*/

}

void TestMylist2()
{
List<int> L;
L.PushFront(1);
L.PushFront(2);
L.PushFront(3);
L.PushFront(4);
L.PushFront(5);
L.PopFront();
PrintMyList(L);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl 迭代器 list