模拟实现STL中的list

来源:互联网 发布:聊天软件营销方案 编辑:程序博客网 时间:2024/06/06 09:41

在前面博客中我已介绍了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 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);}