欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > C++学习笔记(二十九)——list

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

2025/5/8 3:10:05 来源:https://blog.csdn.net/weixin_45857378/article/details/146468427  浏览:    关键词: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); // 在第二个位置插入 7cout << "链表内容: ";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); // 删除所有 2for (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 3system("pause");return 0;
}

注意:

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词