C++容器中list总结及其实现

list

list为双向带头循环链表,由若干结点组成,每个结点都包含一个数据块,前驱指针和后驱指针。list存储在非连续的空间之中,所以相较vector来说list的随机检索能力很弱,检索时间复杂度为O(n)。
优点:

  • 插入,删除元素的代价较小

  • 可在两端进行操作

  • 不需要连续的内存空间
    缺点:

  • 不支持随机访问 [ ], at

  • 内存占用多

相关使用函数:

push_back				尾插
pop_back				尾删
push_front				头插
pop_front				头删
erase					删除指定位置结点
insert					指定位置插入结点
clear					清空list
size					结点个数
resize					重新规定结点个数
swap					交换两个链表
emplace_front			头插(默认构造函数)
emplace_back			尾插(默认构造函数)
splice					合并list
unique					去重
sort					排序(默认从小到大)
merge					按大小合并
reverse					反转

具体请看 http://www.cplusplus.com/reference/list/list/

list迭代器的实现:
利用原生指针进行封装,生成一个自定义类。

template<class T>           //结点
struct ListNode{
    ListNode(const T& val = T())
    :_val(val)
    ,_pre(nullptr)
    ,_next(nullptr)
    {}
    T _val;
    ListNode<T>* _pre;
    ListNode<T>* _next;
};

template<class T, class Pre, class Arc>			//实现iterator类
class _ListIterator{
public:  
    typedef ListNode<T> Node;
    typedef _ListIterator<T,Pre,Arc> Self;    		//Pre 为T& 	Arc为T*
public:
    Node* _node;
    _ListIterator(Node* node)
    :_node(node)
    {
    }
    Arc operator*()						//迭代器解引用是获取数据
    {
        return _node->_val;
    }

    Pre operator->()					//迭代器的->返回的为数据的指针
    {
        return &(_node->_val);
    }

    Self& operator++()          //后置++
    {
        _node = _node->_next;
        return *this;
    }
    
    Self operator++(int)       //前置++
    {
        Self tmp(*this);
        _node = _node->_next;
        return tmp;
    }
    
    Self& operator--()
    {
        _node= _node->_pre;
        return *this;
    }

    Self operator--(int)
    {
        Self tmp(*this);
        _node = _node->_pre;
        return tmp;
    }
    Self& operator+(size_t n)
    {
        for(int i =0; i<n; ++i)
        {
            _node = _node->_next;
        }
        return *this;
    }
    bool operator!=(const Self& l)
    {
        return _node!=l._node;
    }

    bool operator==(const Self& l)
    {
        return _node==l._node;
    }
};

list的部分功能的实现:

template<class T>
class List{
    typedef ListNode<T> Node;
public:    
    typedef _ListIterator<T,T*,T&> iterator;
    typedef _ListIterator<T,const T*, const T&> const_iterator;

    List()
    :_head(new Node)
    {
        _head->_next = _head;
        _head->_pre = _head;
    }
    

    ~List()
    {
        if(_head)
        {
            Clear();
            delete _head;
            _head = nullptr;
        }
    }

    List(List<T>& l)				//拷贝构造	深拷贝
    {
        _head = new Node;
        _head->_next = _head;
        _head->_pre = _head;
        for(auto&e : l)
        {
            PushBack(e);
        }
    }

    List<T>& operator=(const List<T> l)         //传参时进行了拷贝构造
    {
        swap(_head,l._head);
        return *this;  
    }

    void Clear()												//清空
    {
        if(_head)
        {
            Node* cur = _head->_next;
            while(cur != _head)
            {
                Node* next =cur->_next;
                delete cur;
                cur = next;
            }
            _head->_next = _head;
            _head->_pre = _head;   
        }
    }

    void PushBack(const T& val)					//尾插
    {
        Node* cur = new Node(val);  
        Node* pre = _head->_pre;

        cur->_pre = pre;
        cur->_next = _head;
        pre->_next = cur;
        _head->_pre = cur;
    }

 	void PopBack()								//尾删
	{
        Node* cur = _head->_pre;
        cur->_pre->_next = _head;
        _head->_pre = cur->_pre;
        delete cur;
    }

	void PushFront(const T& val)			//头插
	{
        Node* cur = new Node(val);
        Node* next = _head->_next;
        next->_pre = cur;
        cur->_next = next;
        cur->_pre = _head;
        _head->_next = cur;
    }

	void PopFront()						//头删
	{
        Node* cur = _head->_next;
        cur->_next->_pre = _head;
        _head->_next = cur->_next;
        delete cur;
    }  

    void Insert(iterator pos, const T& val)				//迭代器位置插入
    {
        Node* cur = new Node(val);
        Node* _pos = pos._node;

        _pos->_pre->_next = cur;
        cur->_pre = _pos->_pre;
        cur->_next = _pos;
        _pos->_pre = cur;

    }
    //删除迭代器失效
    iterator Erase(iterator pos)
	{
		if (pos != end())
		{
			Node* cur = pos._node;
			Node* prev = cur->_pre;
			Node* next = cur->_next;

			prev->_next = next;
			next->_pre = prev;

			delete cur;
			cur = nullptr;
			pos = iterator(next);
		}

		return pos;
		
	}
    iterator begin()				//普通迭代器
    {
        return iterator(_head->_next);
    }
    iterator end()
    {
        return iterator(_head);
    }
    const_iterator begin()const	//const迭代器
    {
        return const_iterator(_head->_next);
    }
    const_iterator end()const
    {
        return const_iterator(_head);
    }

    bool Empty()
    {
        return _head==_head->_next;
    }

    size_t Size()
    {
        size_t sz = 0;
        Node *cur = _head->_next;
        while(cur != _head)
        {
            sz++;
            cur = cur->_next;
        }
        return sz;
    }
    void Resize(size_t num, const T& val = T())
    {
        size_t sz = Size();
        if(sz<=num)
        {
            for(int i =sz; i<num; ++i)
            {
                PushBack(val);
            }
        }else
        {
            for(int i=0; i<num-sz; ++i)
            {
                PopBack();
            }
        }  
    }
    T& Front()						//返回链表第一个元素
    {
        return _head->_next->_val;
    }
    T& Back()						//返回链表最后一个元素
    {
        return _head->_pre->_val;
    }
    const T& Front()const
    {
        return _head->_next->_val;
    }
    const T& Back()const
    {
        return _head->_pre->_val;
    }
private:
    Node* _head;
};

还有部分功能后面有时间再进一步实现。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值