STL中list的使用及模拟实现

list:带头结点的双向循环链表
我们先来看看在STL中list的各个接口的使用

#include<windows.h>
#include<iostream>
#include <algorithm> 
#include<list>
using namespace std;
//迭代器的使用  
void Testlist()
{
    list<int> l1;
    l1.push_back(1);
    l1.push_back(2);
    l1.push_back(3);
    l1.push_back(4);
    l1.push_back(5);
    //正向迭代器  
    list<int>::iterator it1 = l1.begin();
    while (it1 != l1.end())
    {
        cout << *it1 << " ";
        it1++;
    }
    cout << endl;

    //反向迭代器  
    list<int>::reverse_iterator it2 = l1.rbegin();
    while (it2 != l1.rend())
    {
        cout << *it2 << " ";
        it2++;
    }
    cout << endl;

    //insert:在指定位置的数据之前插入  
    list<int>::iterator it3 = l1.begin();
    it3++;
    l1.insert(it3, 10);
    it3 = l1.begin();
    while (it3 != l1.end())
    {
        cout << *it3 << " ";
        it3++;
    }
    cout << endl;

    //erase:删除指定位置的元素(由于list中没有find接口,引入算法头文件)  
    list<int>::iterator it4 = find(l1.begin(), l1.end(), 10);
    if (it4 != l1.end())
        l1.erase(it4);
    it4 = l1.begin();
    while (it4 != l1.end())
    {
        cout << *it4 << " ";
        it4++;
    }
    cout << endl;

    //迭代器失效  
    list<int>::iterator it5 = l1.begin();
    //while (it5 != l1.end())
    //{
    //  if (*it5 % 2 == 0)
    //      l1.erase(it5);//释放之后it5指向随机空间 
    //}
    //++it5;//对随机空间++,导致程序崩溃 ,若没有删除就会多++一次。


    //解决方法1:先加加,再删除     
    if (*it5 %2==0)
    {
        it5++;
        l1.erase(it5);
    }
    //解决办法2:利用返回值对其进行改进  
    it5 = l1.begin();
    if (*it5 %2==0)
    {
        it5 = l1.erase(it5);
    }
    else
    {
        it5++;
    }



}
int main()
{
    Testlist();
    system("pause");
    return 0;
}

这是我们的运行结果
副本

我们下来参照list来模拟实现

#include<iostream>
#include<assert.h>
using namespace std;


template<class T>
struct __ListNode
{
    T _data;
    __ListNode<T> *_prev;
    __ListNode<T> *_next;

    __ListNode(const T&x)
        :_data(x)
        , _prev(NULL)
        , _next(NULL)
    {}
};
//T,T&,T*
template<class T, class Ref, class Ptr>
struct __ListIterator
{
    typedef __ListNode<T> Node;
    typedef __ListIterator<T, Ref, Ptr> Self;


    __ListIterator(Node *x)
        :_node(x)
    {}

    // T&  出了作用域,对象还存在所以用Ref
    Ref operator*()
    {
        return _node->_data;
    }

    //T*   ->返回数据地址
    Ptr operator->()
    {
        return &_node->_data;
    }
    //前置++
    Self & operator++()
    {
        _node = _node->_next;
        return *this;
    }
    //后置++
    Self operator++(int)
    {
        Node* tmp = _node;  //先保存_node的值
        _node = _node->_next;//让_node指向它的下一个
        return tmp;
    }
    //前置--
    Self &operator--()
    {
        _node = _node->_prev;
        return *this;
    }
    //后置--
    Self operator--(int)
    {
        Node* tmp = _node;//先保存_node的值
        _node = _node->_prev;//让_node指向它的上一个
        return tmp;
    }
    //判断!=
    bool operator != (const Self& s) const
    {
        return _node != s._node;
    }
    //判断==
    bool operator==(const Self &s) const
    {
        return _node == s._node;
    }
    Node *_node;
};


template<class T>
class List
{
public:
    typedef __ListNode<T> Node;
    typedef __ListIterator<T, T&, T*> Iterator;
    //List构造函数
    List()
    {
        _head = new Node(T());
        _head->_prev = _head;
        _head->_next = _head;
    }
    //析构函数
    ~List()
    {
        Clear();
        delete _head;//释放_head
        _head = NULL;//将_head置为空
    }
    //返回类型为迭代器
    Iterator Begin()
    {

        //return Iterator(_head->_next); 
        return _head->_next;//发生隐式类型转换  
        //构造函数和拷贝构造同一步骤使用,编译器会进行自动优化  
    }

    Iterator End()
    {
        //return Iterator(_head);//发生隐式类型转换
        return _head;
    }
    //在pos前插入x
    void Insert(Iterator pos, const T &x)
    {

        Node *next = pos._node;
        Node *prev = next->_prev;
        Node *cur = new Node(x);

        cur->_prev = prev;
        prev->_next = cur;

        cur->_next = next;
        next->_prev = cur;


    }
    //删除指定位置
    Iterator Erase(Iterator pos)
    {
        assert(pos!=End()&&pos._node);
        Node* cur = pos._node;
        Node* prev = cur->_prev;
        Node* next = cur->_next;

        prev->_next = next;
        next->_prev = prev;
        delete cur;
        pos = prev;//实现即删即写(erase之后++,不用else)
        return pos;//防止迭代器失效
    }
    //判断是否为空
    bool Emply()
    {
        return _head == _head->_next;
    }
    //查找
    Iterator Find(const T&x)
    {
        Iterator it = Begin();
        while (it != End())
        {
            if (*it == x)
                return it;
            it++;
        }
        return it;
    }
    //尾插
    void PushBack(const T&x)
    {
        return Insert(End(), x);
    }
    //尾删
    //因为复用了Erase(),所以PopBack的返回值也为Iterator
    Iterator PopBack()
    {
    return Erase(--End());
    }
    //头插
    void PushFront(const T&x)
    {
        return Insert(Begin(), x);
    }
    //头删
    //因为复用了Erase(),所以PopFront的返回值也为Iterator
    Iterator PopFront()
    {
        return Erase(Begin());
    }
    //清空
    void Clear()
    {
        Iterator it = Begin();
        while (it != End())
        {
            Node*del = it._node;
            ++it;
            delete del;
        }

    }
    //打印
    void Print()
    {
        Iterator it = Begin();
        while (it != End())
        {
            cout << *it << " ";
            cout << endl;
            ++it;
        }
    }

protected:
    Node *_head;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值