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

相关推荐
奋斗的小花生1 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
pianmian11 小时前
python数据结构基础(7)
数据结构·算法
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程1 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
UestcXiye2 小时前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang