类模板模拟实现STL中List

List 容器:

list是C++标准模版库(STL,Standard Template Library)中的部分内容。实际上,list容器就是一个双向链表,可以高效地进行插入删除元素。

使用list容器之前必须加上头文件:#include;

list属于std命名域的内容,因此需要通过命名限定:using std::list;也可以直接使用全局的命名空间方式:using namespace std;

构造函数:

  list c1(3); //建一个含三个默认值是0的元素的链表

  list c2(5,2); //建一个含五个元素的链表,值都是2

  list c4(c2); //建一个c2的拷贝构造链表

成员函数:

(1)begin() 返回指向链表第一个元素的迭代器。
(2)end() 返回指向链表最后一个元素之后的迭代器。
(3)operator= 重载赋值运算符。
(4)assign(n,num) 将n个num拷贝赋值给链表c。
(5)front() 返回链表c的第一个元素。
(6)back() 返回链表c的最后一个元素。
(7)empty() 判断链表是否为空。
(8)size() 返回链表c中实际元素的个数。
(9)max_size() 返回链表c可能容纳的最大元素数量。
(10)clear() 清除链表c中的所有元素。
(11)insert(pos,num) 在pos位置插入元素num。
(12)erase(pos)    删除pos位置的元素。
(13)push_back(num) 在末尾增加一个元素。
(14)pop_back() 删除末尾的元素。
(15)push_front(num) 在开始位置增加一个元素。
(16)pop_front() 删除第一个元素。

#include <iostream>
using namespace std;


#pragma once
template<class T>
struct ListNode
{
    ListNode(const T& data = T())
        : _prev(0)
        , _next(0)
        , _data(data)
    {}

    ListNode<T>* _prev;
    ListNode<T>* _next;
    T _data;
};


template<class T, class Ref, class Ptr>
class __ListIterator__
{
    typedef __ListIterator__<T, T&, T*> Iterator;
    typedef __ListIterator__<T, const T&, const T*> const_Iterator;
    typedef __ListIterator__<T, Ref, Ptr> Self;
    typedef ListNode<T>* LinkType;
    typedef Ref Reference;
    typedef Ptr Pointer;

public:
    __ListIterator__(LinkType x = 0) //构造函数
        :_node(x)
    {}

    __ListIterator__(const Iterator& x)  //拷贝构造函数
        :_node(x._node)
    {}

    bool operator == (const Iterator& x)
    {
        return _node == x._node;
    }

    bool operator != (const Iterator& x)
    {
        return _node != x._node;
    }

    Reference operator * ()
    {
        return (*_node)._data;
    }

    Pointer operator -> ()
    {
        return &(operator*());
    }

    Self& operator ++ ()
    {
        _node = _node->_next;
        return *this;
    }

    Self operator ++ (int)
    {
        LinkType temp = _node;
        _node = _node->_next;
        return temp;
    }

    Self& operator -- ()
    {
        _node = _node->_prev;
        return *this;
    }

    Self operator -- (int)
    {
        LinkType temp(_node);
        _node = _node->_prev;
        return temp;
    }

public:
    LinkType _node;
};


template<class T>
class List
{
public:
    typedef ListNode<T> Node;
    typedef T ValueType;
    typedef ValueType& Reference;
    typedef const ValueType& const_Reference;
    typedef ValueType* Pointer;
    typedef const ValueType* const_Pointer;
    typedef Node* LinkType;
    typedef size_t size_type;
    typedef __ListIterator__<T, T&, T*> Iterator;
    typedef __ListIterator__<T, const T&, const T*> const_Iterator;

public:
    List()
    {
        EmptyInit();
    }

    List(size_type n, const T& data = T())  //构造n个数值为data的节点,并连接成一个链表
    {
        _node = new Node(data);
        LinkType NewNode = _node;

        while(n--)
        {
            NewNode->_next = new Node(data);
            NewNode->_prev = _node;
            NewNode->_next->_prev = NewNode;
            NewNode = NewNode->_next;
        }
        NewNode->_next = _node;
        _node->_prev = NewNode;
    }

    List(const List<T>& l)   //拷贝构造函数
    {
        EmptyInit();
        Iterator it = l._node->_next;  
        while(it != _node) 
        {  
            PushBack(*it);  
            ++it;  
        }
    }

    ~List()   //析构函数
    {
        if(_node != NULL)  
        { 
            cout<<"~List()"<<endl;
            delete _node;
            _node = NULL;         
        } 
    }

    List<T>& operator = (const List<T>& l)   //赋值运算符重载
    {
        if(this != &l)
        {
            Iterator temp(l._node);  
            Clear(); 
            delete _node;
            _node = temp._node;

        }
        return *this;
    }

    
    Iterator Begin()  //返回首元素之后位置的迭代器指针
    {
        return _node->_next;
    }

    const_Iterator Begin()const
    {
        return _node->_next;
    }

    Iterator End()  //返回尾元素之后位置的迭代器指针
    {
        return _node;
    }

    const_Iterator End()const
    {
        return _node;
    }

    bool Empty()  //判断链表是否为空
    {
        return _node == _node->_next;
    }

    size_type Size()const   //返回链表c中实际元素的个数
    {
        size_type size = 0;
        Iterator it(_node->_next);
        while(it != _node)
        {
            ++size;
            ++it;
        }
        return size;
    }

    size_type MaxSize()const  //返回链表c可能容纳的最大元素数量
    {
        return size_type(-1);
    }

    Reference Front()   //返回首元素的引用
    {
        return *(Begin());
    }

    const_Iterator Front()const
    {
        return *(Begin());
    }

    Reference Back() // 返回尾元素的引用 
    {
        return *(End()-1);
    }

    const_Reference Back()const
    {
        return *(End()-1);
    }

    Iterator Insert(Iterator pos, const T& x = T()) //在迭代器指针it前插入元素x,返回x迭代器指针
    {
        LinkType temp = new Node(x);
        temp->_next = pos._node;
        temp->_prev = pos._node->_prev;
        pos._node->_prev = temp;
        temp->_prev->_next = temp;
        return temp;
    }

    void PushFront(const T& x)  //list元素首元素前添加一个元素X
    {
        Insert(Begin(), x);
    }

    void PushBack(const T& x)   //list元素尾元素添加一个元素X
    {
        Insert(End(), x);
    }

    Iterator Erase(Iterator pos)   //删除迭代器指针it对应的元素
    {
        LinkType _nextNode = pos._node->_next;
        LinkType _preNode = pos._node->_prev;

        _nextNode->_prev = _preNode;
        _preNode->_next = _nextNode;
        delete pos._node;
        return _nextNode;
    }

    void PopFront() //删除容器首元素,当且仅当容器不为空
    {
        Erase(Begin());
    }

    void PopBack()  //删除容器尾元素,当且仅当容器不为空
    {
        Iterator Del = End();
        Erase(--Del);
    }

    void ReSize(size_type newSize, const T& value = 0) //从新定义链表的长度,超出原始长度部分用num代替,小于原始部分删除。
    {
        if(newSize < Size())
        {
            size_type size = Size() - newSize;

            while(size--)
            {
                PopBack();
            }
        }
        else
        {
            size_t count = newSize - Size();

            while(count)
            {
                size_type size = Size();
                Iterator temp = _node;

                PushBack(value);
                count--;
            }
        }
    }

    void Assign(size_type n, const T& data)
    {
        Iterator pTemp = _node->_next;
        if(Size()>=n)
        {
            for(size_t idx=0;idx<n; ++idx)
            {
                pTemp._node->_data = data;
                ++pTemp;
            }
            for(size_t idx = 0; idx<Size()-n; ++idx)
            {
                PopBack();
            }
        }
        else
        {
            pTemp = _node->_next;
            size_t size = Size();
            for(size_t idx=0; idx<size; ++idx)
            {
                pTemp._node->_data = data;
                ++pTemp;
            }
            for(size_t idx = 0;idx<n-size; ++idx)
            {
                PushBack(data);
            }
        }
        _node = new Node(data);
        LinkType NewNode = _node;

    }

    void Clear()  //删除容器中的所有元素
    {
        Iterator it = Begin();
        while(it != End())
        {
            it = Erase(it);
        }
    }

private:
    void EmptyInit()
    {
        _node = new Node;
        _node->_prev = _node;
        _node->_next = _node;
    }

public:
    LinkType _node;
};

void FunTest()
{
    List<int> l1(1, 5);
    List<int> l2(1, 1);


    l1.PushBack(4);
    l1.PushBack(3);
    l1.PushBack(2);
    l1.PushBack(1);


    l2.Assign(10, 100);
    l2 = l1;
    l1.ReSize(2);
    l1.ReSize(5,100);
    l1.ReSize(10);

    List<int>::Iterator  it = l1.Begin();
    while(it != l1.End())
    {
        cout<<*it<<"->";
        ++it;
    }
    cout<<"NULL"<<endl;

    it = l2.Begin();
    while(it != l2.End())
    {
        cout<<*it<<"->";
        ++it;
    }
    cout<<"NULL"<<endl;

}

int main()
{
    FunTest();
    system("pause");
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值