list,咕咕咕!

1.list的介绍与使用

list是环状双向串行的,有prev,next结点。

cpp 复制代码
list(size_type n,const value_type& val=value_type())
n个val值元素构造
list()  构建空的list
list(const list& x) 拷贝构造函数
list(inputlterator first,inputlterator last) 
用(first,last)区间中的元素构造list

List iterator
begin()+end()  返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin()+rend() 返回end位置+返回begin位置
list的迭代器是双向迭代器,不是随机迭代器,不支持[]随机访问

empty 检测list是否为空,是返回true,否返回false
size 返回list有效节点的个数

front 返回list第一个节点中值的引用
back 返回list最后一个节点中值的引用

push_front 在list首元素前插入值为val的节点
pop_front  删除list第一个节点
push_back 在尾部插入值为val的节点
pop_back 删除list最后一个元素
insert 在list position位置插入值为val的节点
erase 删除list position位置的元素
swap   交换list中2个元素
clear 清空list中的有效元素

list的迭代器也会失效,类似于指针,迭代器失效即迭代器指向的节点无效,该节点被删除了,list的底层结构为带头结点的双向循环链表,在list中插入时是不会导致list的迭代器失效,只有在删除时会失效,erase,失效的只是指向被删除节点的迭代器,其他没事。

cpp 复制代码
 // 链表节点类(声明与实现合并)
    template<class T>
    struct ListNode
    {
        T _val;
        ListNode<T>* _pPre;
        ListNode<T>* _pNext;

        // 构造函数
        ListNode(const T& val = T())
            : _val(val)
            , _pPre(nullptr)
            , _pNext(nullptr)
        {}
    };

    // 链表迭代器类(声明与实现合并)
    template<class T, class Ref, class Ptr>
    struct ListIterator
    {
        typedef ListNode<T>* PNode;
        typedef ListIterator<T, Ref, Ptr> Self;

        PNode _pNode;

        // 构造函数
        ListIterator(PNode pNode = nullptr) : _pNode(pNode) {}
        ListIterator(const Self& l) : _pNode(l._pNode) {}

        // 解引用操作
        Ref operator*() { return _pNode->_val; }
        Ptr operator->() { return &(_pNode->_val); }

        // 前置++
        Self& operator++()
        {
            _pNode = _pNode->_pNext;
            return *this;
        }

        // 后置++
        Self operator++(int)
        {
            Self temp(*this);
            _pNode = _pNode->_pNext;
            return temp;
        }

        // 前置--
        Self& operator--()
        {
            _pNode = _pNode->_pPre;
            return *this;
        }

        // 后置--
        Self operator--(int)
        {
            Self temp(*this);
            _pNode = _pNode->_pPre;
            return temp;
        }

        // 比较操作
        bool operator!=(const Self& l) const { return _pNode != l._pNode; }
        bool operator==(const Self& l) const { return _pNode == l._pNode; }
    };

    // 链表主体类(声明与实现合并)
    template<class T>
    class list
    {
        typedef ListNode<T> Node;
        typedef Node* PNode;
    public:
        typedef ListIterator<T, T&, T*> iterator;
        typedef ListIterator<T, const T&, const T*> const_iterator;

    public:
        // 构造函数:创建空链表(仅头节点)
        list()
        {
            _pHead = new Node;
            _pHead->_pPre = _pHead;
            _pHead->_pNext = _pHead;
        }

        // 填充构造:n个值为value的节点
        list(int n, const T& value = T())
        {
            _pHead = new Node;
            _pHead->_pPre = _pHead;
            _pHead->_pNext = _pHead;
            for (int i = 0; i < n; ++i)
            {
                push_back(value);
            }
        }

        // 迭代器区间构造
        template <class Iterator>
        list(Iterator first, Iterator last)
        {
            _pHead = new Node;
            _pHead->_pPre = _pHead;
            _pHead->_pNext = _pHead;
            while (first != last)
            {
                push_back(*first);
                ++first;
            }
        }

        // 拷贝构造
        list(const list<T>& l)
        {
            _pHead = new Node;
            _pHead->_pPre = _pHead;
            _pHead->_pNext = _pHead;
            const_iterator it = l.begin();
            while (it != l.end())
            {
                push_back(*it);
                ++it;
            }
        }

        // 赋值运算符
        list<T>& operator=(list<T> l)
        {
            swap(l);
            return *this;
        }

        // 析构函数
        ~list()
        {
            clear();
            delete _pHead;
            _pHead = nullptr;
        }

        // 迭代器 begin/end
        iterator begin() { return iterator(_pHead->_pNext); }
        iterator end() { return iterator(_pHead); }
        const_iterator begin() const { return const_iterator(_pHead->_pNext); }
        const_iterator end() const { return const_iterator(_pHead); }

        // 容量操作
        size_t size() const
        {
            size_t count = 0;
            const_iterator it = begin();
            while (it != end())
            {
                ++count;
                ++it;
            }
            return count;
        }

        bool empty() const { return _pHead->_pNext == _pHead; }

        // 元素访问
        T& front()
        {
            if (empty()) throw std::out_of_range("list is empty");
            return _pHead->_pNext->_val;
        }

        const T& front() const
        {
            if (empty()) throw std::out_of_range("list is empty");
            return _pHead->_pNext->_val;
        }

        T& back()
        {
            if (empty()) throw std::out_of_range("list is empty");
            return _pHead->_pPre->_val;
        }

        const T& back() const
        {
            if (empty()) throw std::out_of_range("list is empty");
            return _pHead->_pPre->_val;
        }

        // 元素修改
        void push_back(const T& val) { insert(end(), val); }
        void pop_back() { erase(--end()); }
        void push_front(const T& val) { insert(begin(), val); }
        void pop_front() { erase(begin()); }

        // 在pos前插入节点
        iterator insert(iterator pos, const T& val)
        {
            PNode newNode = new Node(val);
            PNode posNode = pos._pNode;

            newNode->_pPre = posNode->_pPre;
            newNode->_pNext = posNode;
            posNode->_pPre->_pNext = newNode;
            posNode->_pPre = newNode;

            return iterator(newNode);
        }

        // 删除pos位置节点
        iterator erase(iterator pos)
        {
            if (pos == end()) throw std::invalid_argument("cannot erase end iterator");

            PNode posNode = pos._pNode;
            PNode nextNode = posNode->_pNext;

            posNode->_pPre->_pNext = nextNode;
            nextNode->_pPre = posNode->_pPre;
            delete posNode;

            return iterator(nextNode);
        }

        // 清空所有节点
        void clear()
        {
            iterator it = begin();
            while (it != end())
            {
                it = erase(it);
            }
        }

        // 交换两个链表
        void swap(list<T>& l) { std::swap(_pHead, l._pHead); }

    private:
        PNode _pHead;  // 头节点(哨兵节点)
    };
cpp 复制代码
 // 反向迭代器模板(适配器)
    // Iterator:正向迭代器类型;Ref:引用类型;Ptr:指针类型
    template<class Iterator, class Ref, class Ptr>
    struct Reverse_iterator {
        typedef Reverse_iterator<Iterator, Ref, Ptr> Self;
        Iterator _it;  // 存储正向迭代器

        // 构造函数:用正向迭代器初始化
        Reverse_iterator(Iterator it) : _it(it) {}

        // 解引用:反向迭代器的*实际访问正向迭代器的前一个元素
        Ref operator*() const {
            Iterator tmp = _it;  // 拷贝当前正向迭代器
            --tmp;               // 指向前一个元素
            return *tmp;         // 返回前一个元素的引用
        }

        // 箭头操作符:返回前一个元素的指针
        Ptr operator->() const {
            return &(operator*());  // 复用*操作
        }

        // 前置++:反向迭代器向前移动(对应正向迭代器向后移动)
        Self& operator++() {
            --_it;  // 正向迭代器--,反向迭代器实际向前走
            return *this;
        }

        // 前置--:反向迭代器向后移动(对应正向迭代器向前移动)
        Self& operator--() {
            ++_it;  // 正向迭代器++,反向迭代器实际向后走
            return *this;
        }

        // 不等比较:判断两个反向迭代器是否不同
        bool operator!=(const Self& other) const {
            return _it != other._it;
        }

2.list与vector对比

相关推荐
AI科技星11 分钟前
圆柱螺旋运动方程的一步步求导与实验数据验证
开发语言·数据结构·经验分享·线性代数·算法·数学建模
月明长歌41 分钟前
【码道初阶】【Leetcode94&144&145】二叉树的前中后序遍历(非递归版):显式调用栈的优雅实现
java·数据结构·windows·算法·leetcode·二叉树
iAkuya1 小时前
(leetcode) 力扣100 15轮转数组(环状替代)
数据结构·算法·leetcode
.小墨迹1 小时前
C++学习之std::move 的用法与优缺点分析
linux·开发语言·c++·学习·算法·ubuntu
wanghowie1 小时前
01.02 Java基础篇|核心数据结构速查
java·开发语言·数据结构
看见繁华1 小时前
C++ 设计模式&设计原则
java·c++·设计模式
点云SLAM1 小时前
C++ error C2065: “M_PI”: 未声明的标识符 解决方案
开发语言·c++·error c2065·m_pi未声明 解决方案
草莓熊Lotso1 小时前
C++11 核心精髓:类新功能、lambda与包装器实战
开发语言·c++·人工智能·经验分享·后端·nginx·asp.net
欧特克_Glodon2 小时前
C++医学图像处理经典ITK库用法详解<三>: 图像配准模块功能
c++·图像处理·vtk·图像配准
秦苒&2 小时前
【C语言指针四】数组指针变量、二维数组传参本质、函数指针变量、函数指针数组
c语言·开发语言·c++·c#