欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-04 14:37:09
...

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;
};

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

相关标签: 容器