当前位置:首页 > 技术 > 正文内容

C++ STL容器核心概念与基础用法解析

访客 技术 2026年9月30日 9

STL中的容器主要划分为三大体系:顺序型、关联型及适配器型,每种类型针对不同数据操作场景进行了优化。

顺序容器

动态数组 vector

vector 是对传统C数组的增强封装,支持自动扩容和边界安全访问,适用于元素数量动态变化的场景。

// 初始化方式多样
std::vector<double> v1;                     // 空容器
std::vector<double> v2(8, 3.14);           // 8个元素,初始值为π
std::vector<std::vector<int>> grid(5, std::vector<int>(4, 0)); // 5x4二维网格

// 使用初始化列表或迭代器范围
std::vector<int> src = {10, 20, 30, 40};
std::vector<int> copy(src.begin() + 1, src.end() - 1); // [20, 30]

容量管理函数:

  • size():当前元素数量
  • capacity():已分配内存可容纳的最大元素数
  • reserve(n):预分配至少n个元素的空间(不构造对象)
  • resize(n, val):调整元素数量,不足则填充val,超出则截断

常用操作接口:

v.push_back(99);      // 尾部追加
v.pop_back();         // 删除尾部
v.insert(v.begin()+2, 77);  // 在索引2处插入
v.erase(v.begin()+1);       // 删除索引1处元素
v.front(); v.back();        // 首尾元素引用
v.at(3);                    // 安全访问,越界抛异常

算法支持(需包含<algorithm>):

std::sort(v.begin(), v.end(), std::greater<int>()); // 降序排列
std::reverse(v.begin(), v.end());                   // 反转元素顺序

双向链表 list

list 基于节点指针结构,支持任意位置O(1)插入/删除,但不支持随机访问。

std::list<std::string> names;
names.push_front("Alice");
names.push_back("Bob");
names.insert(++names.begin(), "Charlie"); // 在第二个位置插入

// 特有操作
names.merge(other_list);     // 合并有序列表
names.unique();              // 删除相邻重复项
names.splice(names.end(), temp_list); // 拼接另一列表

注意:list迭代器仅支持++/--,不可使用+=算术运算。

双端队列 deque

deque 允许在首尾两端高效增删(O(1)),内部由多个固定块组成,中间插入代价较高。

std::deque<char> dq = {'a', 'b', 'c'};
dq.push_front('X');   // → ['X','a','b','c']
dq.push_back('Y');    // → ['X','a','b','c','Y']

// C++11新增内存回收
dq.shrink_to_fit();   // 释放未使用内存空间

关联容器

集合 set

基于红黑树实现,元素自动排序且唯一,适合需要去重和快速查找的场景。

std::set<int> unique_nums;
unique_nums.insert(5);
unique_nums.insert(3);
auto it = unique_nums.lower_bound(4); // 返回指向≥4的第一个元素

// 集合运算示例
std::set<int> A{1,3,5}, B{3,4,5}, result;
std::set_union(A.begin(), A.end(), B.begin(), B.end(),
               std::inserter(result, result.begin()));
// result = {1,3,4,5}

映射 map

存储键值对,通过key快速检索value,支持下标操作(不存在时自动创建默认值)。

std::map<std::string, int> scores;
scores["Alice"] = 95;          // 直接赋值
scores.insert({"Bob", 87});    // 插入pair

if (scores.find("Charlie") != scores.end()) {
    // 存在则处理
}
scores.erase("Bob");           // 按键删除

允许重复的 multiset/multimap

功能与set/map相同,但允许多个相同键值存在,适用于统计频次等场景。

容器适配器

栈 stack

后进先出结构,默认基于deque实现:

std::stack<int> s;
s.push(10);
s.push(20);
int top_val = s.top(); // 20
s.pop();               // 移除20

队列 queue

先进先出结构:

std::queue<std::string> q;
q.push("first");
q.push("second");
std::cout << q.front(); // "first"
q.pop();

优先队列 priority_queue

默认最大堆,可通过自定义比较器改变排序规则:

// 最小堆实现
std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
min_heap.push(3);
min_heap.push(1);
min_heap.push(4);
std::cout << min_heap.top(); // 输出1

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。