【C++】第六章:STL之模拟实现list及vector和list的区别

一、vector和list的对比

vector是一个可以动态增容的数组。

list是一个带头双向循环链表。

功能vectorlist
底层实现动态增容数组带头双向循环链表
随机访问元素支持随机访问任意位置的元素,O(1)访问不支持随机访问任意位置的元素,O(N)访问
插入和删除元素头尾部元素的操作是O(1),中间位置元素的操作是O(N)任意位置的元素操作都是O(1)
增容空间不足时会动态的增容,增容时首先开辟新空间,拷贝元素,释放旧空间。代价很大没有增容。
空间利用率底层为连续空间,不容易导致空间碎片化,空间利用率高,缓存利用率高,运行时缓存命中率高。底层的节点是动态开辟的,容易造成内存的碎片化,空间利用率不高,缓存利用率也不高。
迭代器实现原生指针需要对原生指针包装进行迭代器运算符的重载
迭代器失效插入元素,有可能会扩容导致所有的迭代器都会失效。删除元素时,当前位置的迭代器和后面的迭代器都会失效。插入元素时,迭代器不会失效。删除元素时,只有当前迭代器会失效。
使用场景高效存储,支持随机元素访问,不关系大量元素的插入效率大量的元素插入和删除,不关系元素的访问效率

总结:vectorlist两个容器是互补的容器,使用起来相辅相成。

二、list的模拟实现

#include <iostream>
using namespace std;

namespace myList
{
    // 双链表中的节点定义
    template<class T>
    struct _list_node 
    {
        T _val;
        _list_node<T>* _prev;
        _list_node<T>* _next;

        _list_node(const T& val = T()):
            _val(val),
            _prev(nullptr),
            _next(nullptr)
        {}
    };

	// 迭代器需要包装一下
    template<class T, class Ref, class Ptr>
    struct _list_iterator
    {
        typedef _list_node<T> node;
        typedef _list_iterator<T, Ref, Ptr> Sef;
    
        node* _pnode;
        
        _list_iterator(node* pnode):
            _pnode(pnode)
        {}

            
        Ref operator* ()
        {
            return _pnode->_val; 
        }

        Ptr operator-> () 
        {
            return &_pnode->_val;// 这里编译器优化掉了一个->,否则应该是->->
        }

        Sef& operator++() // 前置++
        {
           _pnode = _pnode->next;
           return *this;
        }

        Sef operator++(int) // 后置++
        {
            Sef tmp(*this);// 这里需要使用的就是浅拷贝
            _pnode = _pnode->_next;
            return tmp;
        }

        Sef& operator--() // 前置--
        {
            _pnode = _pnode->_prev;
            return *this;
        }

        Sef operator--(int) // 后置--
        {
            Sef tmp(*this);
            _pnode = _pnode->_prev;
            return tmp;
        }

        bool operator!= (const Sef& it) const 
        {
            return _pnode != it._pnode;
        }

        bool operator== (const Sef& it) const 
        {
            return _pnode == it._pnode;
        }

    };



    template<class T>
    struct list 
    {
        typedef _list_node<T> node;
    public:
        // 迭代器及其函数
        typedef _list_iterator<T, T&, T*> iterator;
        typedef _list_iterator<T, const T&, const T*> const_iterator;

        // _head只是一个指针返回迭代器对象的时候需要强制类型转换
        iterator begin()
        {
            return iterator(_head->_next);
        }

        iterator end()
        {
            return iterator(_head);
        }

        const_iterator begin() const 
        {
            return const_iterator(_head->_next); 
        }

        const_iterator end() const 
        {
            return const_iterator(_head);
        }
    

        // 默认构造函数
        list():
            _head(new node)
        {
            _head->_next = _head;
            _head->_prev = _head;
        }

        // 拷贝构造函数
        list(const list<T>& lt):
            _head(new node)
        {
            _head->_next = _head;
            _head->_prev = _head;

            const_iterator it = lt.begin();
            while (it != lt.end())
            {
                push_back(*it);
                it ++;
            }
        }

        // 赋值运算符重载
        list<T>& operator= (list<T> lt) 
        {
            swap(_head, lt._head);
            return *this;
        }
        
        // 赋值运算符的传统写法
        //list<T>& operator= (const list<T>& lt) 
        //{
        //    if (this != &lt)
        //    {
        //        clear();
        //        list<int>::const_iterator it = lt.begin();
        //        while (it != lt.end())
        //        {
        //            push_back(*it);
        //            it ++;
        //        }
        //        return *this;
        //    }
        //}

        // 先将链表中的数据清空,然后将头结点空间释放掉
        ~list()
        {
            clear();
            delete _head;
        }

        void clear()
        {
            iterator it = begin();
            while (it != end())
            {
                it = erase(it);
            }
        }
        
        void push_front(const T& val) 
        {
            insert(begin(), val);
        }
        


        void push_back(const T& val)
        {
            // 复用接口
            insert(end(), val);
            //node* newNode = new node(val);
            //node* tailNode = _head->_prev;
            //
            //tailNode->_next = newNode;
            //newNode->_prev = tailNode;
            //newNode->_next = _head;
            //_head->_prev = newNode;
        }

        // 在pos位置之前插入val
        void insert(iterator pos, const T& val) 
        {
            node* newNode = new node(val);
            node* cur = pos._pnode;
            node* prev = cur->_prev;

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

        }
    

        void pop_front()
        {
            erase(begin());
        }

        void pop_back()
        {
            erase(--end());
        }



        iterator erase(iterator pos) 
        {
            node* cur = pos._pnode;
            node* prev = cur->_prev;
            node* next = cur->_next;
            delete cur;
            cur = nullptr;

            prev->_next = next;
            next->_prev = prev;

            return iterator(next);
        }

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

    private:
        node* _head;
    };
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hyzhang_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值