STL:模拟实现List(迭代器版本的List)

版权声明: https://blog.csdn.net/dangzhangjing97/article/details/81592121

一、什么是List?

List是STL标准库中的一个容器,相当于双向循环的链表,而且此链表有头结点

二、List的优点?

1.通用性好(因为List的实现使用了模板)
2.效率高
3.任意位置的插入和删除操作的时间复杂度为O(1)

三、什么是迭代器?

迭代器本质上是指针

那为什么不直接操作指针,而是把指针封装成迭代器呢?

(1)vector的迭代器可以是原生态的指针
(2)list的迭代器如果使用原生态的指针,那指针++就得不到当前结点的下一个结点,故原生态的指针满足不了list这样的结构,在一个原因是为了实现通用的算法

四、如何给一个容器加迭代器?

使用方法Begin()和End(),这两个方法可以把容器和迭代器联系起来

五、List的实现

1.头插
这里写图片描述

void PushFront(const T&data)
    {
        pNode NewNde = new Node(data);
        _pHead->_pNext->_pPre = NewNode;
        NewNde->_pPre = _pHead;
        NewNde->_pNext = _pHead->_pNext;
        _pHead->_pNext = NewNde;
    }

2.头删
这里写图片描述

void PopFront()
    {
        //空链表
        if (Empty())
            return;
        //链表非空
        pNode pDel = _pHead->_pNext;
        _pHead->_pNext = pDel->_pNext;
        pDel->_pNext->_pPre = _pHead;
        delete pDel;
    }

3.尾插
这里写图片描述

//不用判断空链表,因为链表中有结点的情况包含了空链表的情况
    void PushBack(const T&data)
    {
        pNode pTail = _pHead->_pPre;
        pNode NewNode = new Node(data);
        pTail->_pNext = NewNode;
        NewNode->_pPre = pTail;
        NewNode->_pNext = _pHead;
        _pHead->_pPre = NewNode;
    }

4.尾删
这里写图片描述

void PopBack()
    {
        //空链表
        if (Empty())
            return;
        //链表非空
        pNode pPreTail = _pHead->_pPre->_pPre;
        delete pPreTail->_pNext;
        pPreTail->_pNext = _pHead;
        _pHead->_pPre = pPreTail;
    }

5.任意位置的插入
这里写图片描述

//不用判断空链表的情况
    //双向链表一般是吧data插入pos的前面,单链表是吧data插入到pos的后面
    pNode Insert(pNode pos, const T&data)
    {
        pNode NewNode = new Node(data);
        pos->_pPre->_pNext = NewNode;
        NewNode->_pNext = pos;
        NewNode->_pPre = pos->_pPre;
        NewNode->_pNext = pos;
        return NewNode;
    }

6.任意位置的删除
这里写图片描述

pNode Erase(pNode pos)
    {
        pNode pRet = pos->_pNext;
        //空链表
        if (Empty())
            return NULL;
        //非空链表
        pos->_pPre->_pNext = pos->_pNext;
        pos->_pNext->_pPre = pos->_pPre;
        delete pos;
        return pRet;
    }

7.清空链表中所有的结点
这里写图片描述

void Clear()
    {
        pNode pDel = _pHead->_pNext;
        while (!Empty())
        {
            pDel = _pHead->_pNext;
            _pHead->_pNext = pDel->_pNext;
            delete pDel;
        }
        _pHead->_pPre = _pHead;
    }

七、源代码

#include<iostream>
using namespace std;

template<class T>
struct ListNode
{
    ListNode(const T&data = T())
    :_pNext(NULL)
    , _pPre(NULL)
    , _data(data)
    {}
    ListNode<T>*_pNext;
    ListNode<T>*_pPre;
    T _data;
};

////模拟实现迭代器
template<class T>
class ListIterator
{
    typedef ListNode<T>* pNode;
    typedef ListIterator<T> Self;
public:
    //构造函数
    ListIterator()
        :_pCur(NULL)
    {}
    ListIterator(pNode pCur)
        :_pCur(pCur)
    {}
    //拷贝构造函数
    ListIterator(const Self& s)
        :_pCur(s._pCur)
    {}
    //重载前置++
    Self& operator++()
    {
        _pCur = _pCur->_pNext;
        return*this;
    }
    //重载后置++
    Self operator++(int)
    {
        Self temp(*this);
        _pCur = _pCur->_pNext;
        return temp;
    }
    //重载前置--
    Self& operator--()
    {
        _pCur = _pCur->_pPre;
        return _pCur;
    }
    //重载后置--
    Self operator--(int)
    {
        Self temp(*this);
        _pCur = _pCur->_pPre;
        return temp;
    }
    //重载不等于和等于
    bool operator!=(const Self& s)
    {
        return _pCur != s._pCur;
    }
    bool operator==(const Self& s)
    {
        return _pCur == s._pCur;
    }
    //重载对指针的解引用
    T& operator*()
    {
        return _pCur->_data;
    }
    //重载箭头访问符
    T* operator->()
    {
        return &(_pCur->_data);
    }
private:
    pNode _pCur;
};

//模拟实现List
template<class T>
class List
{
public:
    typedef ListNode<T> Node;
    typedef ListNode<T>* pNode;
public:
    typedef ListIterator<T> Iterator;
public:
    //构造函数
    List()
    {
        //构建链表头结点
        CreateListHead();
    }
    List(T*array,size_t size)
    {
        CreateListHead();
        for (size_t i = 0; i < size; ++i)
            PushBack(array[i]);
    }
    //拷贝构造函数
     List(const List<T>&l);
    //赋值运算符重载
    List<T>& operator=(const List<T>& l);
    //析构函数
    ~List()
    {
        Clear();
        delete _pHead;
        _pHead = NULL;
    }
    //////////////////////////////////////////////////////////////////////////////////////////////
    ////迭代器的接口
    Iterator Begin()
    {
        return Iterator(_pHead->_pNext);
    }
    Iterator End()
    {
        return Iterator(_pHead);
    }
    /////////////////////////////////////////////////////////////////////////////////////////////

    /////////////////////////////////////////////////////////////////////////////////////////////
    //以下是List的一些操作
    /////////////////////////////////////////////////////////////////////////////////////////////
    //尾插
    //不用判断空链表,因为链表中有结点的情况包含了空链表的情况
    void PushBack(const T&data)
    {
        pNode pTail = _pHead->_pPre;
        pNode NewNode = new Node(data);
        pTail->_pNext = NewNode;
        NewNode->_pPre = pTail;
        NewNode->_pNext = _pHead;
        _pHead->_pPre = NewNode;
    }
    //尾删
    void PopBack()
    {
        //空链表
        if (Empty())
            return;
        //链表非空
        pNode pPreTail = _pHead->_pPre->_pPre;
        delete pPreTail->_pNext;
        pPreTail->_pNext = _pHead;
        _pHead->_pPre = pPreTail;
    }
    //头插
    //不用判断空链表的情况
    void PushFront(const T&data)
    {
        pNode NewNde = new Node(data);
        _pHead->_pNext->_pPre = NewNode;
        NewNde->_pPre = _pHead;
        NewNde->_pNext = _pHead->_pNext;
        _pHead->_pNext = NewNde;
    }
    //头删
    void PopFront()
    {
        //空链表
        if (Empty())
            return;
        //链表非空
        pNode pDel = _pHead->_pNext;
        _pHead->_pNext = pDel->_pNext;
        pDel->_pNext->_pPre = _pHead;
        delete pDel;
    }
    //任意位置的插入
    //不用判断空链表的情况
    //双向链表一般是吧data插入pos的前面,单链表是吧data插入到pos的后面
    pNode Insert(pNode pos, const T&data)
    {
        pNode NewNode = new Node(data);
        pos->_pPre->_pNext = NewNode;
        NewNode->_pNext = pos;
        NewNode->_pPre = pos->_pPre;
        NewNode->_pNext = pos;
        return NewNode;
    }
    //任意位置的删除
    pNode Erase(pNode pos)
    {
        pNode pRet = pos->_pNext;
        //空链表
        if (Empty())
            return NULL;
        //非空链表
        pos->_pPre->_pNext = pos->_pNext;
        pos->_pNext->_pPre = pos->_pPre;
        delete pos;
        return pRet;
    }
    //判断链表是否为空链表
    bool Empty()const
    {
        return _pHead->_pNext == _pHead;
    }
    //获取链表的结点数
    size_t Size()
    {
        size_t count = 0;
        pNode pCur= _pHead->_pNext;
        while (pCur!=_pHead)
        {
            count++;
            pCur = pCur->_pNext;
        }
    }
    //将链表中的所有结点置空
    void Clear()
    {
        pNode pDel = _pHead->_pNext;
        while (!Empty())
        {
            pDel = _pHead->_pNext;
            _pHead->_pNext = pDel->_pNext;
            delete pDel;
        }
        _pHead->_pPre = _pHead;
    }
    //重载输出运算符
    friend ostream& operator << (ostream& _cout, const List<int>& l)
    {
        for (size_t i = 0; i < l.Size(); ++i)
            _cout << l[i] << "  ";
        return _cout;
    }
private:
    //创建链表头结点
    void CreateListHead()
    {
        _pHead = new Node;
        _pHead->_pNext = _pHead;
        _pHead->_pPre = _pHead;
    }
private:
    pNode _pHead;
};

void Print(List<int>& l)//打印链表
{
    List<int>::Iterator it = l.Begin();
    while (it != l.End())
    {
        cout << *it << "---->";
        ++it;//用前置++,不会创建临时对象,比后置++的效率高
    }
    cout << "NULL" << endl;
}
//找数据data在链表中的的位置
template<class Iterator,class T>
Iterator Find(Iterator start, Iterator finish, const T&data)
{
    while (start != finish)
    {
        if (*start == data)
            return start;
        ++start;
    }
    return finish;
}
void TestList()
{
    List<int> L;
    L.PushBack(1);
    L.PushBack(2);
    L.PushBack(3);
    L.PushBack(4);
    L.PushBack(5);
    Print(L);
    L.PopFront();
    L.PopFront();
    Print(L);
}
int main()
{
    TestList();
    system("pause");
    return 0;
}
阅读更多

没有更多推荐了,返回首页