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

相关推荐
老前端的功夫几秒前
【Java从入门到入土】28:Stream API:告别for循环的新时代
java·开发语言·python
qq_43528792几秒前
第9章 夸父逐日与后羿射日:死循环与进程终止?十个太阳同时值班的并行冲突
java·开发语言·git·死循环·进程终止·并行冲突·夸父逐日
止语Lab13 分钟前
从手动到框架:Go DI 演进的三个拐点
开发语言·后端·golang
yaoxin52112327 分钟前
397. Java 文件操作基础 - 创建常规文件与临时文件
java·开发语言·python
小短腿的代码世界31 分钟前
Qt日志系统深度解析:从qDebug到企业级日志框架
开发语言·qt
REDcker1 小时前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
Yzzz-F2 小时前
Problem - 2205D - Codeforces
算法
我命由我123453 小时前
Kotlin 开发 - lateinit 关键字
android·java·开发语言·kotlin·android studio·android-studio·android runtime
智者知已应修善业3 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
Halo_tjn3 小时前
Java Set集合相关知识点
java·开发语言·算法