• C++
  • C++ std::list 零基础完整教程

  • @ 2026-9-18 19:49:42

C++ std::list 零基础完整教程

std::list 是双向链表容器,头文件:#include <list> 特点:

  1. 双向链表,每个节点存数据 + 指向前、后节点的指针
  2. 随机访问很差,不能用 list[下标],不支持 []
  3. 在中间插入、删除元素效率极高,不需要移动大量元素
  4. 迭代器(iterator)不会因为插入删除失效(被删元素迭代器除外)
  5. 元素不连续存放在内存,和 vector(连续数组)形成对比

⚠️重点:list 不能像数组一样用下标 lst[0] lst[1]!想要访问元素靠迭代器遍历。

常用成员函数表格

函数 作用
lst.size() 返回当前元素个数
lst.empty() 判断是否为空,空返回true
lst.clear() 清空所有元素
lst.push_back(x) 尾部添加元素x
lst.push_front(x) 头部添加元素x(vector没有这个!list优势)
lst.pop_back() 删除尾部元素
lst.pop_front() 删除头部元素
lst.front() 获取第一个元素
lst.back() 获取最后一个元素
lst.insert(iter, x) 在迭代器iter位置前面插入x
lst.erase(iter) 删除迭代器iter指向的元素
lst.remove(x) 删除容器中所有等于x的元素(list独有)
lst.reverse() 链表反转,倒序
lst.sort() 链表内部排序,不需要sort算法,成员函数
lst.merge(lst2) 把lst2合并到lst,lst2变空,要求两个list预先有序

完整示例代码,逐行注释

#include <iostream>
#include <list>   // 使用std::list必须头文件
using namespace std;

int main()
{
    // 1.定义list容器,存储int类型数据
    list<int> lst1;          // 创建空的int链表
    list<int> lst2 = {10,20,30,40};  // 创建同时初始化4个元素

    // ============增加元素============
    lst1.push_back(100);   // 在链表【尾部】压入 100
    lst1.push_back(200);
    lst1.push_front(50);   // 在链表【头部】压入 50  → list特有高效操作
    lst1.push_front(10);
    // 现在 lst1:  10 , 50 , 100 , 200

    // ============获取头尾元素============
    cout << "链表第一个元素 front():" << lst1.front() << endl; //10
    cout << "链表最后一个元素 back():" << lst1.back() << endl; //200

    cout << "链表大小 size() = " << lst1.size() << endl;  //4
    cout << "是否为空 empty() = " << lst1.empty() << endl;//0(false)

    // ============迭代器 iterator 遍历list============
    // list不能用 []下标!!只能用迭代器遍历
    cout << "\n迭代器遍历lst1:" << endl;
    // list<int>::iterator 迭代器类型,相当于链表的"指针"
    for(list<int>::iterator it = lst1.begin(); it != lst1.end(); it++)
    {
        // *it 取出迭代器指向的数据
        cout << *it << "  ";
    }
    cout << endl;

    // C++11 范围for循环,更简单,推荐日常写
    cout << "范围for遍历:" << endl;
    for(int num : lst1)
    {
        cout << num << "  ";
    }
    cout << endl;

    // ============insert 在指定位置插入元素============
    // begin() 返回指向第一个元素的迭代器
    auto it = lst1.begin();  // auto自动推导类型,等价 list<int>::iterator
    it++;   // it向后移动一步,指向第二个元素(50)
    lst1.insert(it, 666);   // 在it位置前面插入666
    // 链表变成:10 , 666 , 50 , 100 , 200

    // ============erase 删除迭代器指向的元素============
    it = lst1.begin();
    it++;
    lst1.erase(it);  // 删除it指向的666
    // 链表回到:10 ,50 ,100 ,200

    // ============remove 删除所有等于某个值的元素【list独有】============
    lst1.push_back(50);
    lst1.push_back(50);
    // lst1: 10,50,100,200,50,50
    lst1.remove(50); // 删除全部值=50的元素
    // lst1:10,100,200

    // ============reverse() 反转链表============
    lst1.reverse();
    cout << "\nreverse反转之后:" << endl;
    for(int num : lst1) cout << num << " ";
    cout << endl;
    //输出:200 100 10

    // ============sort() list自带排序成员函数============
    lst1.sort(); // 默认从小到大升序
    cout << "sort排序后:" << endl;
    for(int num : lst1) cout << num << " ";
    cout << endl;
    //输出:10 100 200

    // ============merge合并两个有序list============
    list<int> la = {1,3,5};
    list<int> lb = {2,4,6};
    la.merge(lb); // lb全部合并进la,lb变为空链表
    cout << "\nmerge合并结果 la:" << endl;
    for(int x : la) cout << x << " ";
    cout << "   lb.size()=" << lb.size() << endl;

    // ============pop 删除头、尾元素============
    lst1.pop_front(); // 删除头部元素
    lst1.pop_back();  // 删除尾部元素

    // ============clear清空全部元素============
    lst1.clear();
    cout << "\nclear之后 size=" << lst1.size() << endl;

    return 0;
}

迭代器基础说明

lst.begin()   // 返回迭代器:指向链表第一个元素
lst.end()     // 返回迭代器:指向【最后一个元素的后面】,不是有效元素!
  • it++:迭代器向后移动到下一个节点(list可以it++ it--双向移动)
  • list迭代器不支持 it + 3 这种跳跃!不能直接跳几步,只能一步一步++/--

❌错误写法:it = lst.begin() + 2; list不允许!vector可以。 ✅正确:it++; it++;

list vs vector 对比(重点,考试、写代码必看)

特性 std::list(双向链表) std::vector(动态数组)
内存存储 内存不连续,节点分散 内存连续一块空间
随机访问 [下标] ❌不支持 ✅支持
头部插入删除 ⭐极快 O(1) 慢,需要移动全部元素 O(n)
尾部插入删除 快 ⭐极快
中间插入删除 ⭐极快 O(1) 慢 O(n)
迭代器失效 删除元素,仅被删元素迭代器失效 插入删除会大量迭代器失效
排序 自带.sort()成员函数 用全局sort()算法

使用场景选择:

  1. 需要频繁在头部、中间插入删除 → 优先 list
  2. 需要频繁按下标访问数据,尾部增删 → 优先 vector

常见坑点

  1. ❌不能写 list<int> a; cout << a[0]; list没有下标运算符!编译报错
  2. it + n 跳跃迭代器不能用于list,只能it++、it--一步移动
  3. merge()合并前两个list最好预先有序;merge之后第二个list会变成空
  4. remove(x) 直接删除所有等于x的元素,vector没有这个函数
  5. end()是末尾后面,不是最后一个元素,循环条件一定写 it != lst.end()

小练习

  1. 创建list,依次插入 1,2,3,4,5;头部插入0;尾部插入6;遍历输出
  2. 删除所有等于3的元素,反转链表输出
  3. 两个有序list做merge合并输出

0 条评论

目前还没有评论...