• 【C++ STL序列容器】list 双向链表


    【 1. 基本原理 】

    • list 容器,又称双向链表容器,该容器的底层是以双向链表的形式实现的。这意味着:list 容器中的元素可以分散存储在内存空间里。
    • list 双向链表容器的存储结构:
      list 容器中各个元素的前后顺序是靠指针来维系的,每个元素都配备了 2 个指针,分别指向它的前一个元素和后一个元素。其中第一个元素的前向指针总为 null,因为它前面没有元素;同样,尾部元素的后向指针也总为 null。
      在这里插入图片描述
    • 优点
      基于双向链表这样的存储结构,list 容器具有一些其它容器(array、vector 和 deque)所不具备的优势,即 list 双向链表 可以在序列已知的任何位置快速插入或删除元素(时间复杂度为O(1)),并且 在 list 容器中移动元素效率也比其它容器高
    • 缺点
      使用 list 容器的缺点是 list 不能通过位置直接访问元素,而array 和 vector就可以。举个例子,如果要访问 list 容器中的第 6 个元素,它 不支持 容器对象名[6] 这种语法格式,正确的做法是 访问元素需要从容器中第一个元素或最后一个元素开始遍历容器,直到找到该位置
    • 应用场景
      实际场景中,如何需要对序列进行大量添加或删除元素的操作,而直接访问元素的需求却很少,这种情况建议使用 list 容器存储序列。
    • list 容器以模板类 list(T 为存储元素的类型)的形式在 头文件 中,并位于 std 命名空间 中。

    【 2. list 的创建 】

    2.1 创建1个空的 list

    • 和空 array 容器不同,空的 list 容器在创建之后仍可以添加元素,因此创建 list 容器的方式很常用。
    list<int> values;
    
    • 1

    2.2 创建一个包含 n 个元素的 list(默认值)

    • 创建 list容器 对象 valuse,其中包含 10 个元素,每个元素的值都为相应类型的默认值(int类型的默认值为 0):
    list<int> values(10);
    
    • 1

    2.3 创建一个包含 n 个元素的 list(赋初值)

    • 创建一个包含 n 个元素的 list 容器,并为每个元素指定初始值。
    list<int> values(10, 5);
    
    • 1

    2.4 通过1个 list 初始化另一个 list

    • 在已有 list 容器的情况下,通过拷贝该容器可以创建新的 list 容器:
      必须保证新旧容器存储的元素类型一致
    list<int> value1(10,5);
    list<int> value2(value1);
    
    • 1
    • 2

    2.5 拷贝其他类型容器的指定元素创建 list

    • 通过拷贝其他类型容器(或者普通数组)中指定区域内的元素,可以创建新的 list 容器:
    //拷贝普通数组,创建list容器
    int a[] = { 1,2,3,4,5 };
    list<int> values(a, a+5);
    
    //拷贝其它类型的容器,创建 list 容器
    array<int, 5>arr{ 11,12,13,14,15 };
    list<int>values(arr.begin()+2, arr.end());//拷贝arr容器中的{13,14,15}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    【 3. list 的成员函数 】

    成员函数功能
    begin()返回指向容器中第一个元素的双向迭代器。
    end()返回指向容器中最后一个元素所在位置的下一个位置的双向迭代器。
    rbegin()返回指向最后一个元素的反向双向迭代器。
    rend()返回指向第一个元素所在位置前一个位置的反向双向迭代器。
    cbegin()和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
    cend()和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
    crbegin()和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
    crend()和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
    empty()判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
    size()返回当前容器实际包含的元素个数。
    max_size()返回容器所能包含元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
    front()返回第一个元素的引用。
    back() 返回最后一个元素的引用。
    assign()用新元素替换容器中原有内容。
    emplace_front()在容器头部生成一个元素。该函数和 push_front() 的功能相同,但效率更高。
    push_front()在容器头部插入一个元素。
    pop_front()删除容器头部的一个元素。
    emplace_back()在容器尾部直接生成一个元素。该函数和 push_back() 的功能相同,但效率更高。
    push_back()在容器尾部插入一个元素。
    pop_back()删除容器尾部的一个元素。
    emplace()在容器中的指定位置插入元素。该函数和 insert() 功能相同,但效率更高。
    insert()在容器中的指定位置插入元素。
    erase()删除容器中一个或某区域内的元素。
    swap()交换两个容器中的元素,必须保证这两个容器中存储的元素类型是相同的。
    resize()调整容器的大小。
    clear()删除容器存储的所有元素。
    splice()将一个 list 容器中的元素插入到另一个容器的指定位置。
    remove(val)删除容器中所有等于 val 的元素。
    remove_if()删除容器中满足条件的元素。
    unique()删除容器中相邻的重复元素,只保留一个。
    merge()合并两个事先已排好序的 list 容器,并且合并之后的 list 容器依然是有序的。
    sort()通过更改容器中元素的位置,将它们进行排序。
    reverse()反转容器中元素的顺序。
    • list 容器还有一个swap(x , y) 非成员函数(其中 x 和 y 是存储相同类型元素的 list 容器),它和 swap() 成员函数的功能完全相同,仅使用语法上有差异
    • begin() 函数 、end() 函数
      C++ 11 标准库新增加了 begin() 和 end() 这 2 个函数,和 list 容器包含的 begin() 和 end() 成员函数不同,标准库提供的这 2 个函数的操作对象,既可以是容器,还可以是普通数组。
      • 当操作对象是容器时,它和 容器包含的 begin() 和 end() 成员函数的功能完全相同
      • 如果操作对象是 普通数组,则 begin() 函数返回的是指向数组第一个元素的指针,同样 end() 返回指向数组中最后一个元素之后一个位置的指针(注意不是最后一个元素)。

    实例

    #include 
    #include 
    using namespace std;
    int main()
    {
        //创建空的 list 容器
        list<double> values;
        //向容器中添加元素
        values.push_back(3.1);
        values.push_back(2.2);
        values.push_back(2.9);
        cout << "values size:" << values.size() << endl;
        //对容器中的元素进行排序
        values.sort();
        //使用迭代器输出list容器中的元素
        for (list<double>::iterator it = values.begin(); it != values.end(); ++it) {
            cout << *it << " ";
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

  • 相关阅读:
    【JAVA数据结构】包装类与认识泛型
    Python少儿编程小课堂(三)入门篇(3)
    Jaca定时任务-01-进程级别的Timer,ScheduledExecutorService,springtask
    #与##的用法
    【C语言数据结构】1.单链表
    利用python批量读取大量Excel表格文件中指定内容并汇总
    java8 Stream字段排序sorted()
    【MM小贴士】从 purchase 到 payment 全流程演示
    AcWing:第56场周赛
    浅拷贝和深拷贝?仔细搞懂你
  • 原文地址:https://blog.csdn.net/qq_44431690/article/details/138091645