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

C++学习笔记(二十九)——list

一、std::list

(1)list与其适用场景

std::list 是 C++的STL(标准模板库)中的双向链表容器,支持高效的插入、删除操作,适用于频繁在容器中间插入或删除元素的场景。

特点:

  • 双向链表(Doubly Linked List),支持双向迭代。
  • 任意位置插入/删除效率高O(1))。
  • 不支持随机访问O(n) 查找)。
  • 遍历比 vector(由于链表节点分散存储)。

适用场景:

  • 频繁插入/删除
  • 不需要随机访问
  • 链表结构(如 LRU 缓存)

(2)list vs vector

特性list(链表)vector(动态数组)
存储结构双向链表(分散存储)连续内存(数组)
插入/删除O(1) 任意位置插入/删除O(n) 位置插入/删除(尾部 O(1))
随机访问O(n)(不支持 [] 访问O(1)(支持 [] 访问)
遍历性能较慢(跳转指针)较快(CPU缓存友好)
适用场景频繁插入/删除快速随机访问

list 在需要高效插入/删除的情况下比 vector 更合适,但如果需要频繁访问元素vector 更优。

二、std::list 的常用函数

函数作用
push_back(val)尾部插入元素
push_front(val)头部插入元素
pop_back()删除尾部元素
pop_front()删除头部元素
insert(pos, val)在指定位置插入元素
erase(pos)删除指定位置元素
remove(val)删除所有匹配的元素
size()获取链表大小
front()获取链表首元素
back()获取链表尾元素
clear()清空链表
empty()判断链表是否为空
sort()对链表排序
reverse()反转链表
unique()删除连续重复元素
merge(other_list)合并两个有序链表
迭代器函数作用
begin()指向首元素
end()指向尾后位置
rbegin()指向末元素(反向遍历)
rend()指向首元素前的位置(反向遍历)

三、std::list的基本使用

(1) 插入与删除

示例:

#include <iostream>
using namespace std;
#include <list>

int main() {
    list<int> myList;

    myList.push_back(10);   // 尾部插入
    myList.push_front(5);   // 头部插入
    myList.insert(++myList.begin(), 7); // 在第二个位置插入 7

    cout << "链表内容: ";
    for (int val : myList)
    {
        cout << val << " "; // 5 7 10
    }
    cout << endl;

    myList.pop_back();   // 删除尾部元素
    myList.pop_front();  // 删除头部元素

    cout << "删除后: ";
    for (int val : myList)
    {
        cout << val << " "; // 7
    }
    cout << endl;
    
    system("pause");
    return 0;
}

注意:

  • push_back(val) —— 尾部插入元素;pop_back() —— 删除尾部元素。
  • push_front(val) —— 头部插入元素;pop_front() —— 删除头部元素。

(2) 删除特定值

示例:

#include <iostream>
using namespace std;
#include <list>

int main() {
    list<int> myList = { 1, 2, 2, 3, 4, 2, 5 };

    myList.remove(2); // 删除所有 2

    for (int val : myList)
    {
        cout << val << " "; // 1 3 4 5
    }
    cout << endl;

    system("pause");
    return 0;
}

(3) 排序与反转

示例:

#include <iostream>
using namespace std;
#include <list>

void printList(list<int> L)
{
    for (int val : L)
    {
        cout << val << " ";
    }
    cout << endl;
}

int main() {
    list<int> myList = { 3, 1, 4, 1, 5, 9 };

    myList.sort(); // 默认升序
    printList(myList);

    myList.reverse(); // 反转
    printList(myList);
    
    system("pause");
    return 0;
}

注意:

  • sort() 默认为升序排列,再执行reverse()后为逆序排列;

(4) 去重

示例:

#include <iostream>
using namespace std;
#include <list>

void printList(list<int> L)
{
    for (int val : L)
    {
        cout << val << " ";
    }
    cout << endl;
}

int main() {
    list<int> myList = {1, 1, 2, 3, 2, 4, 5, 5, 6};
    printList(myList);

    myList.unique(); // 仅删除相邻的重复元素
    printList(myList);
    
    system("pause");
    return 0;
}

注意:

  • myList.unique() 删除链表myList中的连续重复元素(连续重复时,只保留一个副本)。

四、std::list 的应用

(1) LRU(最近最少使用)缓存

LRU(Least Recently Used) 是一种基于访问时间排序的缓存淘汰策略,
其核心思想是:‌最近被访问的数据在未来被访问的概率更高‌,因此当缓存容量满时优先淘汰最久未被使用的数据‌

示例:

#include <iostream>
using namespace std;
#include <list>
#include <unordered_map>

class LRUCache {
public:
    LRUCache(int cap) : capacity(cap) {}

    void access(int key)
    {
        if (cacheMap.find(key) != cacheMap.end())
        {
            cacheList.erase(cacheMap[key]); // 若重复访问,删除最早访问记录,保留最近访问记录
        }
        else if (cacheList.size() == capacity)
        {
            int last = cacheList.back();
            cacheList.pop_back(); // 若达到容量限制,删除最近最少使用的数据
            cacheMap.erase(last);
        }

        cacheList.push_front(key);
        cacheMap[key] = cacheList.begin();
    }

    void print()
    {
        for (int val : cacheList)
        {
            cout << val << " ";
        }
        cout << endl;
    }

private:
    int capacity; // 缓存空间的最大容量
    list<int> cacheList; // 缓存数据
    unordered_map<int, list<int>::iterator> cacheMap; // 访问记录
};

int main() {
    LRUCache cache(3);
    cache.access(1);
    cache.access(2);
    cache.access(3);

    cache.access(4); // 1 被淘汰
    cache.access(2);
    cache.print(); // 2 4 3

    system("pause");
    return 0;
}

注意:

  • LRUCache cache(3); 中链表最大容量为3
  • 连续访问数据1,2,3后,达到最大容量,继续访问数据4时,删除最近最少使用的数据1。

http://www.kler.cn/a/612182.html

相关文章:

  • 【Linux网络-poll与epoll】epollserver设计(两个版本 Reactor)+epoll理论补充(LT ET)
  • vue ts+Windi CSS
  • CTFshow【命令执行】web29-web40 做题笔记
  • 未来工程项目管理新走向:云原生软件赋能绿色可持续建设
  • Kafka 面试备战指南
  • eureka与ribbon混合使用
  • Linux设置SSH免密码密钥登录
  • Netty和Project Reactor如何共同处理大数据流?
  • 无人机抗风测试技术要点概述!
  • failed to load steamui.dll”错误:Steam用户的高频崩溃问题解析
  • LLaMA-Factory使用实战
  • Elasticsearch 之 ElasticsearchRestTemplate 聚合查询
  • Java版Manus实现来了,Spring AI Alibaba发布开源OpenManus实现
  • Linux驱动开发--IIC子系统
  • 基于HTML5的3D魔方项目开发实践
  • leetcode 150. 逆波兰表达式求值
  • 22、web前端开发之html5(三)
  • HarmonyOS Next~鸿蒙系统开发类Kit深度解析与应用实践
  • 211、【图论】建造最大岛屿(Python)
  • 计算机网络——传输层(TCP)