当前位置: 首页 > news >正文

【C++】:STL详解 —— list类

目录

list的概念

list的构造函数 

list的大小

size()

resize()

empty()

list的插入

push_front()和emplace_front()

push_back()和emplace_back()

insert()和emplace()

list的删除

pop_front()

pop_back()

erase()

remove() 

remove_if()  

 unique()  

clear()

list的拼接

splice()

merge()

list的迭代器

迭代器类型

begin()和end()

rbegin()和rend()

list中的元素访问

front()

back()

list的逆置


list的概念

  1. list是一种可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
  2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立结点当中,在结点中通过指针指向其前一个元素和后一个元素。
  3. list与forward_list非常相似,最主要的不同在于forward_list是单链表,只能进行单方向迭代。
  4. list与其他容器相比,list通常在任意位置进行插入、删除元素的执行效率更高。
  5. list 和 forward_list最大的缺陷是不支持在任意位置的随机访问,其次,list还需要一些额外的空间,以保存每个结点之间的关联信息(对于存储的类型较小元素来说这可能是一个重要的因素)。

list的构造函数 

默认构造函数:创建一个空链表

list<T> list_name;

填充构造函数:创建包含 n 个相同值的链表

list<int> list2(5, 10);  // 包含5个值为10的节点:{10, 10, 10, 10, 10}

范围构造函数:通过迭代器范围 [first, last) 初始化链表

int arr[] = {1, 2, 3};
list<int> list3(arr, arr + 3);  // 复制数组内容:{1, 2, 3}

拷贝构造函数:通过另一个链表深拷贝初始化

list<int> list4(list3);  // 拷贝 list3 的内容:{1, 2, 3}

移动构造函数:通过移动另一个链表的资源初始化(高效转移所有权)

list<int> list5(move(list4));  // list4 变为空,list5 接管其内容

初始化列表构造函数(C++11 起):通过初始化列表直接赋值

list<int> list6 = {4, 5, 6};  // 直接初始化:{4, 5, 6}

 

list的大小

size()

  • size():返回当前元素数量
#include <list>
#include <iostream>

int main() {
    list<int> mylist = {1, 2, 3, 4, 5};
    cout << "Size: " << mylist.size(); // 输出 5
    return 0;
}

resize()

  • 若 n < size():截断链表,仅保留前 n 个元素。

  • 若 n > size():扩展链表,新增元素默认初始化为 T()(或指定 value)。

std::list<int> mylist = {1, 2, 3};

mylist.resize(5);     // 扩展为 {1, 2, 3, 0, 0}(填充默认值0)
mylist.resize(2);     // 截断为 {1, 2}
mylist.resize(4, 99); // 扩展为 {1, 2, 99, 99}

empty()

检查链表是否为空(等价于 size() == 0

std::list<int> mylist;
if (mylist.empty()) 
{
    std::cout << "List is empty!";
}

list的插入

push_front()和emplace_front()

  • push_front (const value_type& val)
    • ​​​在头部插入元素(拷贝构造)。
  • emplace_front (Args&&... args);(C++11 起)
    •  在头部直接构造元素(避免临时对象拷贝)

头部插入

list<int> mylist;
mylist.push_front(10);  // 链表内容:{10}
mylist.push_front(20);  // 链表内容:{20, 10}

push_back()和emplace_back()

尾部插入

  • push_front (const value_type& val)
    • ​​​在尾部插入元素(拷贝构造)。
  • emplace_front (Args&&... args);(C++11 起)
    •  在尾部直接构造元素(避免临时对象拷贝)
mylist.push_back(30);   // 链表内容:{20, 10, 30}

insert()和emplace()

  • insert(iterator pos, const T& value)  
    • 在迭代器 pos 指向的位置前插入元素(拷贝构造)。
  • emplace(iterator pos, Args&&... args)(C++11 起)
    • 在 pos 位置直接构造元素(更高效)。 

指定位置插入

示例一:插入单个元素

list<int> mylist = { 1, 2, 3 };
mulist.insert(mylist.begin(), 1);
// mylist { 1, 1, 2, 3 }

示例二:插入多个相同元素

list<int> mylist = { 1, 2, 3 };
list<int>::iterator it = mylist.begin();
myList.insert(it, 3, 100);     // 插入3个100
// mylist { 100, 100, 100, 1, 2, 3 }

示例三:插入范围元素

list<int> mylist = { 1, 2, 3 };
list<int>::iterator it = mylist.end();

vector<int> vec = {5, 6, 7};
myList.insert(it, vec.begin(), vec.end());  // 在末尾插入vector内容
// mylist { 1, 2, 3, 4, 5, 6 }

list的删除

pop_front()

头部删除,移除链表第一个元素

list<int> mylist = { 1, 2, 3 };
mylist.pop_front();    // mylist:{ 2, 3 }

pop_back()

尾部删除,移除链表最后一个元素

list<int> mylist = { 1, 2, 3 };
mylist.pop_back();    // mylist:{ 1, 2 }

erase()

任意位置删除

erase(iterator pos)
删除迭代器 pos 指向的元素

list<int> mylist = {10, 20, 30, 40};

auto it = mylist.begin() + 2;
mylist.erase(it);        // 删除30 → {10, 20, 40}

erase(iterator first, iterator last)
删除迭代器范围 [first, last) 内的元素(左闭右开)

list<int> mylist = {1, 2, 3, 4, 5};
auto it = mylist.erase(v.begin() + 1, v.begin() + 3); 
// 删除元素 2 和 3,v = {1, 4, 5}
// it 指向 4

remove() 

用于删除容器当中特定值的元素

list<int> list1 = { 1, 2, 3, 4,3, 3 };
lt.remove(3); //删除容器当中所有值为3的元素
// list1 { 1, 2, 4 }

remove_if()  

用于删除容器当中满足条件的元素。

bool single_digit(const int& val)
{
	return val < 10;
}

list<int> list1 = { 1, 2, 3, 4,3, 3, 10 };
lt.remove_if(single_digit); / /删除容器当中值小于10的元素
// list1 { 10 }

 unique()  

用于删除容器当中连续的重复元素。 

list<int> list1 = { 1, 4 ,3 ,3, 2, 2, 3 };
list1.sort();     //将容器当中的元素排为升序
list1.unique();     //删除容器当中连续的重复元素
// list1 { 1, 2, 3, 4 }

clear()

移除所有元素,size() 变为 0

list<int> mylist = { 1, 2, 3 };
mylist.clear();    // mylist.size() == 0

list的拼接

splice()

可以将一个链表的元素移动到另一个链表中,无需复制元素。

示例一:合并整个链表

    list<int> list1 = {1, 2, 3};
    list<int> list2 = {4, 5, 6};

    // 将 list2 的所有元素移动到 list1 的末尾
    list1.splice(list1.end(), list2);

    // 输出结果: 1 2 3 4 5 6
    for (auto num : list1) 
    {
        std::cout << num << " ";
    }

示例 2: 移动单个元素

list<int> list1 = {1, 2, 3};
list<int> list2 = {4, 5, 6};

// 将 list2 的第一个元素移动到 list1 的末尾
auto it = list2.begin();
list1.splice(list1.end(), list2, it);    // list1{ 1, 2, 3 , 4 }

示例 3: 移动元素区间 

list<int> list1 = {1, 2, 3};
list<int> list2 = {4, 5, 6};

// 将 list2 中从第二个元素到末尾的元素移动到 list1 的末尾
auto start = list2.begin();
start++;
auto end = list2.end();
list1.splice(list1.end(), list2, start, end);    
// list1 { 1, 2, 3, 5, 6 }

merge()

如果两个链表已排序,可以用 merge() 合并并保持有序:

std::list<int> list1 = {1, 3, 5};
std::list<int> list2 = {2, 4, 6};

// 合并后 list2 变为空,list1 包含 1 2 3 4 5 6
list1.merge(list2);

list的迭代器

迭代器类型

迭代器类型说明示例
iterator可读写的正向迭代器list.begin()
const_iterator只读的正向迭代器list.cbegin()
reverse_iterator可读写的反向迭代器list.rbegin()
const_reverse_iterator只读的反向迭代器list.crbegin()

begin()和end()

  • begin():返回指向第一个元素的迭代器。

  • end():返回指向最后一个元素之后位置的迭代器(尾后迭代器)。

    list<int> lt(10, 2);
	//正向迭代器遍历容器
	list<int>::iterator it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}

rbegin()和rend()

  • rbegin():返回指向最后一个元素之后位置的迭代器(尾后迭代器)。

  • rend():返回指向第一个元素的迭代器。

    list<int> lt(10, 2);
	//反向迭代器遍历容器
	list<int>::reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		cout << *rit << " ";
		rit++;
	}

支持的运算符

  • ++it 和 it++:向前移动

  • --it 和 it--:向后移动

  • *it:解引用获取元素值

  • it1 == it2 和 it1 != it2:比较是否指向同一位置

不支持的运算符

  • it + n 或 it[n](不支持随机访问)

  • it1 < it2(仅支持相等性比较)

 

list中的元素访问

front()

获取list容器第一个元素

    list<int> lt = { 0, 1, 2, 3, 4 };

	cout << lt.front() << endl; //0

back()

获取list容器最后一个元素

   list<int> lt = { 0, 1, 2, 3, 4 };

	cout << lt.back() << endl; //4

list的逆置

reverse()

list<int> list1 = { 1, 2, 3, 4, 5 };

list1.reverse();
// list1 { 5, 4, 3, 2, 1 }  

相关文章:

  • mapbox基础,加载background背景图层
  • 模拟算法.
  • 核桃派开发板的vnc viewer连接
  • 京东云鼎消息队列订阅详细步骤(已完成:order_order_finish)
  • ERP项目实施流程及存在的风险
  • 机器学习介绍与数据集
  • Amazon Outposts:构建混合云的安全堡垒,让数据安全“零距离”
  • Python基于机器学习的微博舆情情感分析系统,微博评论情感分析可视化系统(全新升级)
  • Redis 之持久化机制(The Persistence Mechanism of Redis)
  • 字符串_ 反转字符串II
  • 【学写LibreCAD】1 创建核心模块库
  • 数据解析与处理
  • 我的AI工具箱Tauri版-InteriorDecorationDesignDrawing平面设计图生成房屋所有室内的效果图
  • SGMII(Serial Gigabit Media Independent Interface)详解
  • C++ 二叉搜索树与双向链表_牛客题霸_牛客网
  • Docker Desktop 社区版安装配置全流程指南(Windows平台)
  • Docker快速使用指南
  • Spring Boot @Component注解介绍
  • 清华大学DeepSeek赋能职场教程下载,清华大学DeepSeek文档下载(完成版下载)
  • 在VSCode中安装jupyter跑.ipynb格式文件
  • 道指跌逾100点,特斯拉涨近5%
  • 重视体重管理,筑牢健康基石
  • 澎湃研究所“营商环境研究伙伴计划”启动
  • 专访|高圆圆:像鸟儿一样,柔弱也自由
  • 北京:下调个人住房公积金贷款利率
  • 古龙逝世四十周年|中国武侠文学学会与多所高校联合发起学术纪念活动