C++中的list容器详解

C++中的list容器详解

1. list概述

list是C++ STL中的双向链表容器,支持在任何位置高效插入和删除元素。与vectordeque不同,list不提供随机访问能力,但提供了高效的插入和删除操作。

2. 基本特性

  • 双向链表:每个元素包含指向前后元素的指针
  • 高效插入/删除 :在任何位置插入/删除都是O(1)O(1)O(1)时间复杂度
  • 无随机访问:不支持下标操作,必须通过迭代器遍历
  • 不连续存储:元素分散在内存中

3. 头文件与声明

cpp 复制代码
#include <list>
using namespace std;

list<int> lst1;               // 空list
list<string> lst2(10);        // 包含10个默认构造的string
list<double> lst3(5, 3.14);   // 包含5个3.14
list<char> lst4 = {'a', 'b', 'c'};  // 初始化列表

4. 构造函数与初始化

4.1 默认构造

cpp 复制代码
list<int> lst;

4.2 填充构造

cpp 复制代码
list<int> lst(10);        // 10个默认初始化的int(0)
list<int> lst(5, 100);    // 5个100

4.3 范围构造

cpp 复制代码
int arr[] = {1, 2, 3};
list<int> lst(arr, arr+3);

4.4 拷贝构造

cpp 复制代码
list<int> lst2(lst1);

5. 容量操作

5.1 size()

cpp 复制代码
cout << lst.size();  // 返回元素数量

5.2 empty()

cpp 复制代码
if(lst.empty()) {
    cout << "List is empty";
}

5.3 max_size()

cpp 复制代码
cout << lst.max_size();  // 返回list可容纳的最大元素数

5.4 resize()

cpp 复制代码
lst.resize(10);      // 调整为10个元素,新增元素默认初始化
lst.resize(15, 5);   // 调整为15个元素,新增元素初始化为5

6. 元素访问

6.1 front()

cpp 复制代码
lst.front() = 5;     // 修改第一个元素
int first = lst.front();  // 访问第一个元素

6.2 back()

cpp 复制代码
lst.back() = 8;      // 修改最后一个元素
int last = lst.back();  // 访问最后一个元素

7. 修改操作

7.1 push_back()

cpp 复制代码
lst.push_back(10);   // 在尾部插入10

7.2 push_front()

cpp 复制代码
lst.push_front(5);   // 在头部插入5

7.3 pop_back()

cpp 复制代码
lst.pop_back();      // 删除尾部元素

7.4 pop_front()

cpp 复制代码
lst.pop_front();     // 删除头部元素

7.5 insert()

cpp 复制代码
auto it = lst.insert(lst.begin(), 15);  // 在头部插入15
lst.insert(it, {1, 2, 3});              // 在指定位置插入多个元素

7.6 erase()

cpp 复制代码
lst.erase(lst.begin());              // 删除第一个元素
lst.erase(lst.begin(), lst.end());   // 删除所有元素

7.7 clear()

cpp 复制代码
lst.clear();  // 清空所有元素

7.8 swap()

cpp 复制代码
list<int> lst2;
lst.swap(lst2);  // 交换两个list的内容

8. 特殊操作

8.1 splice()

cpp 复制代码
list<int> lst2 = {4, 5, 6};
lst.splice(lst.end(), lst2);  // 将lst2所有元素移动到lst尾部
lst.splice(lst.begin(), lst2, lst2.begin());  // 移动lst2的第一个元素

8.2 remove()

cpp 复制代码
lst.remove(5);  // 删除所有值为5的元素

8.3 remove_if()

cpp 复制代码
lst.remove_if([](int n){ return n%2 == 0; });  // 删除所有偶数

8.4 unique()

cpp 复制代码
lst.unique();  // 删除连续重复元素

8.5 merge()

cpp 复制代码
list<int> lst2 = {4, 5, 6};
lst.sort(); lst2.sort();
lst.merge(lst2);  // 合并两个已排序list

8.6 sort()

cpp 复制代码
lst.sort();  // 升序排序
lst.sort(greater<int>());  // 降序排序

8.7 reverse()

cpp 复制代码
lst.reverse();  // 反转list

9. 迭代器

9.1 begin() & end()

cpp 复制代码
for(auto it = lst.begin(); it != lst.end(); ++it) {
    cout << *it << " ";
}

9.2 rbegin() & rend()

cpp 复制代码
for(auto rit = lst.rbegin(); rit != lst.rend(); ++rit) {
    cout << *rit << " ";  // 反向遍历
}

10. 完整示例

cpp 复制代码
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;

int main() {
    // 创建并初始化list
    list<int> lst = {2, 3, 4};
    
    // 头部和尾部操作
    lst.push_front(1);    // 头部插入1
    lst.push_back(5);     // 尾部插入5
    
    // 访问元素
    cout << "First element: " << lst.front() << endl;
    cout << "Last element: " << lst.back() << endl;
    
    // 插入元素
    auto it = next(lst.begin(), 2);  // 获取第3个位置的迭代器
    lst.insert(it, {7, 8, 9});       // 在第3个位置插入7,8,9
    
    // 删除元素
    lst.pop_front();      // 删除头部元素
    lst.remove(8);        // 删除所有8
    
    // 特殊操作
    list<int> lst2 = {10, 11, 12};
    lst.splice(lst.end(), lst2);  // 合并lst2到lst
    
    lst.sort();                   // 排序
    lst.unique();                 // 去重
    
    // 遍历list
    cout << "All elements: ";
    for(int num : lst) {
        cout << num << " ";
    }
    cout << endl;
    
    // 容量信息
    cout << "Size: " << lst.size() << endl;
    cout << "Is empty: " << (lst.empty() ? "Yes" : "No") << endl;
    
    return 0;
}

11. 性能提示

  1. 在任何位置插入/删除元素性能都很好(O(1)O(1)O(1))
  2. 查找元素需要遍历(O(n)O(n)O(n))
  3. 迭代器在插入/删除操作后仍然有效(除非删除的是迭代器指向的元素)
  4. 适合频繁插入/删除但不需随机访问的场景
相关推荐
就不掉头发2 小时前
I/O复用
运维·服务器·c语言·开发语言
梦里小白龙2 小时前
JAVA 策略模式+工厂模式
java·开发语言·策略模式
安_3 小时前
js 数组splice跟slice
开发语言·前端·javascript
程序员葫芦娃3 小时前
【Java毕设项目】基于SSM的旅游资源网站
java·开发语言·数据库·编程·课程设计·旅游·毕设
Pocker_Spades_A3 小时前
飞算Java在线学生成绩综合统计分析系统的设计与实现
java·开发语言·java开发·飞算javaai炫技赛
Yuer20253 小时前
用 Rust 做分布式查询引擎之前,我先写了一个最小执行 POC
开发语言·分布式·rust
Francek Chen3 小时前
【飞算JavaAI】智能开发助手赋能Java领域,飞算JavaAI全方位解析
java·开发语言·人工智能·ai编程·飞算
tryxr3 小时前
继承存在的意义、特点、使用方法
java·开发语言·接口
lkbhua莱克瓦243 小时前
基础-函数
开发语言·数据库·笔记·sql·mysql·函数