C++ 容器(四)——List操作

一、List定义

内部核心是双向链表结构:

1、list内部以双向链表形式存储元素,每个节点包含指向前一个节点和后一个节点的指针。

2、动态大小:list的大小可以根据需要动态增长或缩小,不需要预先指定容器的大小。

3、插入和删除效率高:由于双向链表的特点,list在任意位置进行插入和删除操作的效率都很高,不受元素数量的影响。

4、不连续内存存储:list的元素在内存中不是连续存储的,因此插入和删除操作不会造成元素的移动。

只要运行逻辑和C语言链表一致,就是在C语言的基础上进行函数封装,方便用户使用。

二、List操作

1)List添加及提取

cpp 复制代码
std::list<int> myList;         // 创建一个空的list
myList.push_back(1);           // 在list末尾插入元素1
myList.push_front(2);          // 在list头部插入元素2
int firstElement = myList.front();     // 获取list的第一个元素
int lastElement = myList.back();       // 获取list的最后一个元素

2) 插入元素

cpp 复制代码
std::list<int>::iterator it = myList.begin();    // 获取list的迭代器
std::advance(it, 2);                             // 将迭代器it前进2个位置
myList.insert(it, 3);                // 在迭代器it指定的位置插入元素3

3)删除指定位置的元素

cpp 复制代码
std::list<int>::iterator it = myList.begin();   // 获取list的迭代器
std::advance(it, 2);                            // 将迭代器it前进2个位置
myList.erase(it);                               // 删除迭代器it指定的元素

注:删除操作,对比vector动态数组,可以直接删除,不需要移动其他元素。

4) 遍历list

cpp 复制代码
for (std::list<int>::iterator it = myList.begin(); it != myList.end(); ++it) {
            std::cout << *it << " ";         // 使用迭代器it访问list中的元素
}

注:要遍历list,只能使用迭代器,不能使用索引,动态访问。

5) 清空list

cpp 复制代码
myList.clear();               // 清空list中的所有元素

三、案例分析

  1. 创建一个list容器,存储整型数据。
  2. 将用户输入的5个整数依次插入到list容器中。
  3. 遍历list容器,计算并输出其中所有整数的总和。
  4. 删除list容器中值为偶数的元素,并输出删除后的list容器内容。
cpp 复制代码
#include <iostream>
#include <list>
using namespace std;

int main()
{
    list<int> lst;
    int arr[5] = {0};
    int sum = 0;
    cout<<"请依次输入5个整数:";
    for(int i = 0;i < 5;i++)
    {
        cin>>arr[i];
        lst.push_back(arr[i]);
    }

    cout<<"lst的元素有:";
    for(auto it = lst.begin();it != lst.end();it++)
    {
        if(it != --lst.end())
        {
            cout<<*it<<",";
        }
        else
        {
            cout<<*it;
        }
        sum += *it;
    }
    cout<<endl;
    cout<<"所有元素的和是:"<<sum<<endl;

    for(auto it = lst.begin();it != lst.end();it++)
    {
        if(*it % 2 == 0)
        {
            it = lst.erase(it);
        }
    }

    cout<<"删除后的lst元素有:";
    for(auto it = lst.begin();it != lst.end();it++)
    {
        if(it != --lst.end())//lst.erase(it)后,迭代器it就失效了,而在下一次循环中使用失效的迭代器会导致未定义行为,需要返回的下一个有效迭代器赋值给it
        {
            cout<<*it<<",";
        }
        else
        {
            cout<<*it;
        }
    }
    return 0;
}

运行结果:

cpp 复制代码
请依次输入5个整数:1 2 3 4 5
lst的元素有:1,2,3,4,5
所有元素的和是:15
删除后的lst元素有:1,3,5

四、List原理

std::list 链表,顺序容器 链式分配内存:一个个节点动态分配内存,然后通过指针链接成一串

cpp 复制代码
template< class T, class Allocator = std::allocator<T> > class list

五、List总结

插入和删除元素的效率高,不会造成元素的移动。

支持在任意位置进行插入和删除操作。

不需要预先指定容器的大小。

list是一种高效的双向链表容器,适用于需要频繁进行插入和删除操作的场景,但对于需要频繁访问元素的场景,不是最佳选择。

相关推荐
ULTRA??1 分钟前
排序算法之快排与TIMSORT的比较测试,python
c++·python·算法·golang
m0_471199632 分钟前
【场景】笛卡尔积
开发语言·前端·javascript
Brookty6 分钟前
Java并发编程核心的基础知识
java·开发语言·java-ee·多线程·线程安全
hellotutu6 分钟前
Java 读取 Excel 文件
java·开发语言·excel
胡萝卜3.07 分钟前
构建安全的C++内存管理体系:从RAII到智能指针的完整解决方案
运维·开发语言·c++·人工智能·安全·智能指针·raii
拾光Ծ8 分钟前
【优选算法】双指针算法:专题一
数据结构·c++·算法
Watermelo6178 分钟前
【前端实战】从 try-catch 回调到链式调用:一种更优雅的 async/await 错误处理方案
前端·javascript·网络·vue.js·算法·vue·用户体验
MSTcheng.9 分钟前
【C++】如何快速实现一棵支持key或key-value的二叉搜索树?关键技巧一文掌握!
开发语言·c++·算法·二叉搜索树
ByNotD0g9 分钟前
Go 泛型 in 1.25
开发语言·后端·golang
野生风长12 分钟前
从零开始的c语言:指针高级应用(下)(回调函数,qsort函数模拟实现, strlen和sizeof)
java·c语言·开发语言·c++·算法