蓝桥杯C++:数据结构(功能导向速查)

核心按操作功能分类,每个功能下讲解不同数据结构的实现方式、用法、核心特点及跨结构区别,贴合算法刷题实际使用场景,所有内容均来自原文,无额外拓展。

一、插入操作

核心实现:push_back / push / insert / 数组模拟链表专属插入

1. vector:push_back(x)
  • 尾部插入 ,示例:vector<int> v; v.push_back(10);
  • 特点:底层连续内存,均摊时间复杂度 O (1),扩容时会重新分配内存。
2. stack(栈):push(x)
  • 栈顶插入 x,示例:stack<int> st; st.push(5);
  • 后进先出(LIFO)。
3. queue(队列):push(x)
  • 队尾插入 x,示例:queue<int> q; q.push(3);
  • 先进先出(FIFO)。
4. priority_queue(优先队列):push(x)
  • 底层自动排序(默认大根堆),示例:priority_queue<int> heap; heap.push(8);
  • 自动维护堆序,时间复杂度 O (logn),仅能从堆顶操作。
5. 数组模拟链表:头插 / 任意位置插(专属逻辑)
  • 头插法 :id 从 1 开始,0 为结束标记,示例:

    复制代码
    int h=0, e[1000], ne[1000], id=0;
    id++; e[id]=x; ne[id]=ne[h]; ne[h]=id;
  • 任意位置 p 后插id++; e[id]=x; ne[id]=ne[p]; ne[p]=id;

  • 任意位置插入时间复杂度 O (1),竞赛首选(优于 STL list)。

6. set/unordered_set:insert(x)
  • 插入单个元素 x,
    • 示例:
      • set<int> s; s.insert(2);
      • unordered_set<int> us; us.insert(2);
  • set 自动升序 + 去重,unordered_set 无序 + 去重;底层分别为红黑树(O (logn))、哈希表(平均 O (1))。
7. map/unordered_map:insert({key, value})
  • 插入键值对,示例:map<int, string> m; m.insert({1, "abc"});
  • map 按键升序 + 键唯一,unordered_map 无序 + 键唯一;
  • map 的[]也可实现插入(键不存在时自动创建),如m[2] = "def";

插入操作 跨结构核心区别

  1. 插入位置限制:vector / 栈 / 队列仅支持固定位置插入(尾 / 栈顶 / 队尾),链表支持任意位置插入,红黑树 / 哈希表无显式位置(自动排序 / 哈希)。
  2. 插入特性:set/map/unordered 系列自动去重(map 按 key 去重),其余结构无自动去重;优先队列插入自动排序。
  3. 时间复杂度:链表 /vector/ 栈 / 队列插入为 O (1),红黑树(set/map)为 O (logn),哈希表(unordered 系列)平均 O (1)。

二、删除操作

核心实现:pop_back / pop / erase / 数组模拟链表专属删除

1. vector:pop_back()
  • 尾部删除 ,无返回值,示例:v.pop_back();
  • O (1) 时间复杂度。
2. stack(栈):pop()
  • 栈顶删除 ,无返回值,示例:st.pop();
  • 删栈顶前需用empty()判空,避免崩溃。
3. queue(队列):pop()
  • 队头删除 ,无返回值,示例:q.pop();
  • 删队头前需用empty()判空。
4. priority_queue(优先队列):pop()
  • 堆顶删除 ,无返回值,示例:heap.pop();
  • 删堆顶前需判空,删除后自动维护堆序。
5. 数组模拟链表:删除指定位置后元素(专属逻辑)
  • 跳过被删除节点,示例:void erase(int p) { if(ne[p]) ne[p] = ne[ne[p]]; }
  • O (1) 时间复杂度,删除前需判断ne[p]!=0(避免空节点)。
6. set/unordered_set:erase(x) / erase(迭代器)
  • erase(x)删除所有值为 x 的元素,erase(迭代器)删除指定元素,示例:s.erase(2); s.erase(s.find(3));
  • set 为 O (logn),unordered_set 平均 O (1)。
7. map/unordered_map:erase(key) / erase(迭代器)
  • 删除,示例:m.erase(1); m.erase(m.find(2));
  • 与 set 一致,++仅操作对象为 key,而非元素值++。

删除操作 跨结构核心区别

  1. 删除位置限制:与插入位置强绑定(如栈删栈顶、队列删队头),仅链表 /set/map/unordered 系列支持指定元素 / 位置删除。
  2. 删除方式:vector / 栈 / 队列仅支持无参删除(固定位置),其余结构需指定元素 / 键 / 迭代器 / 位置。
  3. 返回值 :所有删除操作均无返回值(需先访问再删除)。

三、元素访问操作

核心实现:[] / front() / back() / top() / 迭代器解引用 / 数组直接访问

1. vector:v[idx] / front() / back()
  • v[idx]按下标访问(下标从 0 开始),front()取首元素,back()取尾元素,示例:v[0]; v.front();
  • 特点:随机访问 O (1),访问前需判断下标 < size (),避免越界。
2. 数组模拟链表:e[id]直接访问
  • 通过节点 id 访问元素,示例:e[1];(id 从 1 开始,0 为无效)
3. stack(栈):top()
  • 仅访问栈顶元素 ,示例:st.top();
  • 访问前必须判空 。
4. queue(队列):front() / back()
  • 用法front()取队头,back()取队尾,示例:q.front(); q.back();
  • 访问前必须判空,无法访问中间元素。
5. priority_queue(优先队列):top()
  • 用法 :仅访问堆顶元素 (优先级最高),示例:heap.top();
  • 特点:访问前必须判空。
6. set/unordered_set:迭代器解引用*it
  • [],需通过 find / 遍历获取迭代器,再解引用,示例:auto it = s.find(2); cout << *it;
  • 特点 :迭代器仅支持 ++/--,不支持随机访问(如it+1)。
7. map/unordered_map:m[key] / 迭代器it.first/it.second
  • m[key]按键访问值(键不存在则自动插入);迭代器中it.first为 key,it.second为 value,示例:m[1]; auto it = m.find(1); it->second;
  • 特点 :unordered_map 同 map;multimap 不支持[](键不唯一)。

访问操作 跨结构核心区别

  1. 是否支持随机访问 :仅 vector 支持(下标[]),其余所有结构均不支持。
  2. 访问范围限制:栈 / 队列 / 优先队列仅支持访问固定位置(栈顶 / 队头 / 堆顶等),无法访问中间元素。
  3. 专属访问方式:set/unordered_set 仅能通过迭代器解引用;map/unordered_map 支持按键访问和迭代器键值分离访问。
  4. 注意点[]在 vector 中是下标访问 ,在 map 中是按键访问 ,并非同一概念;unordered 系列无lower_bound/upper_bound

四、查找操作

核心实现:find() / count() / lower_bound() / upper_bound()(链表无内置查找,需手动遍历)

1. vector:无内置查找函数,需手动遍历 / 使用算法库find
  • 连续内存,遍历查找 O (n),无专属查找接口。
2. 数组模拟链表:无内置查找,需手动遍历
  • for(int i=ne[h];i!=0;i=ne[i]) { if(e[i]==x) // 找到 }
  • 特点:遍历查找 O (n),无专属接口。
3. stack/queue/priority_queue:无任何查找接口
  • 特点:仅支持固定位置的增删查,无法查找指定元素。
4. set/map:find(x) / count(x) / lower_bound(x) / upper_bound(x)
  • 用法
    • find(x):set 查值、map 查键,返回迭代器(不存在则返回end());
    • count(x):返回 x 的出现次数(set/map 中仅 0/1,即存在 / 不存在);
    • lower_bound(x):返回≥x 的最小元素 / 键迭代器;
    • upper_bound(x):返回 > x 的最小元素 / 键迭代器。
  • 底层红黑树,所有查找操作 O (logn)。
5. unordered_set/unordered_map:find(x) / count(x)
  • 与 set/map 一致(set 查值、map 查键);
    • find(x):set 查值、map 查键,返回迭代器(不存在则返回end());
    • count(x):返回 x 的出现次数(set/map 中仅 0/1,即存在 / 不存在);
    • lower_bound(x):返回≥x 的最小元素 / 键迭代器;
    • upper_bound(x):返回 > x 的最小元素 / 键迭代器。
  • 特点 :底层哈希表,平均 O (1);lower_bound/upper_bound(无序,无排序基础)。

查找操作 跨结构核心区别

  1. 是否有内置查找:stack/queue/priority_queue 无任何查找接口;vector / 链表需手动遍历;红黑树 / 哈希表系列有专属高效查找接口。
  2. 查找效率:哈希表系列(unordered)平均 O (1) > 红黑树系列(set/map)O (logn) > vector / 链表 O (n)。
  3. 查找拓展接口 :仅有序的 set/map 支持lower_bound/upper_bound,无序的 unordered 系列无此接口。
  4. 查找对象 :set/unordered_set 查元素值 ,map/unordered_map 查,二者不可混淆。

五、 size() / empty() / clear() / resize(n)

核心实现:size() / empty()(所有结构均支持,接口统一)

通用用法
  • size():返回实际元素个数,需加(),示例:v.size(); s.size(); st.size();
  • empty():返回布尔值(true = 空,false = 非空),需加(),示例:q.empty(); heap.empty();
跨结构核心注意
  1. 接口完全统一 :所有数据结构的size()/empty()用法、格式一致,无差异。
  2. 前置判断 :使用top()/front()/back()/pop()等操作前,必须用empty()判空,避免访问空容器崩溃。
  3. vector 注意v.size()返回无符号整数,避免与 int 比较出现越界(如i < v.size()而非i <= v.size()-1)。

六、清空 / 重置操作

核心实现:clear() / resize(n) / 手动重置(链表)

1. vector:clear() / resize(n)
  • clear():清空所有元素,size 变为 0,示例:v.clear();
  • resize(n):调整大小,n > 原大小补 0,n < 原大小截断尾部,示例:v.resize(5);
2. set/unordered_set/map/unordered_map:clear()
  • 清空所有元素,示例:s.clear(); m.clear();
  • 清空后 size 为 0,可重新插入元素。
3. stack/queue/priority_queue:无clear(),需手动清空
  • 通过循环判空 + 删除实现,示例:while(!st.empty()) st.pop();
4. 数组模拟链表:手动重置
  • 重置头节点 h=0、节点计数 id=0,示例:h=0; id=0;
  • 无内置清空接口,需手动恢复初始状态。

清空操作 跨结构核心区别

  1. 是否有内置clear():vector/set/map/unordered 系列有,栈 / 队列 / 优先队列 / 数组模拟链表无。
  2. clear()的处理方式 :栈 / 队列 / 优先队列用循环删 ,链表用手动重置初始值
  3. vector 的 resize:不仅能清空,还能调整容器大小,是其专属拓展功能,其余结构无。

七、额外高频操作:遍历

核心实现:范围 for / 下标遍历 / 迭代器遍历 / 链表专属遍历

1. vector:下标遍历 / 范围 for / 迭代器
  • 下标:for(int i=0;i<v.size();i++) cout << v[i];
  • 范围 for:for(auto x : v) cout << x;
2. 数组模拟链表:专属遍历(按 ne 指针)
  • for(int i=ne[h];i!=0;i=ne[i]) cout << e[i];(0 为结束标记)
3. set/unordered_set/map/unordered_map:范围 for / 迭代器
  • set:for(auto x : s) cout << x; / for(auto it=s.begin();it!=s.end();it++) cout << *it;
  • map:for(auto x : m) cout << x.first << x.second;(it.first=key,it.second=value)
4. stack/queue/priority_queue:无内置遍历方式,需手动导出后遍历
  • 用法 :循环取顶 / 队头 + 删除,存入临时容器再遍历,示例:

    复制代码
    stack<int> st, tmp;
    while(!st.empty()) { tmp.push(st.top()); st.pop(); }
    while(!tmp.empty()) { cout << tmp.top(); tmp.pop(); }

遍历操作 跨结构核心区别

  1. 遍历便捷性:vector(下标遍历)> 范围 for(set/map/unordered/vector)> 链表专属遍历 > 栈 / 队列手动遍历。
  2. 迭代器限制 :set/map/unordered 系列的迭代器仅支持 ++/--,不支持随机访问(如it+1);vector 迭代器支持随机访问。
  3. 有序性 :set/map 遍历结果默认升序 ,unordered 系列遍历无序 ,其余结构遍历为插入顺序(vector / 链表 / 栈 / 队列)。
  4. 栈 / 队列:无原生遍历接口,需牺牲原容器(导出后删除),或复制容器后遍历。
相关推荐
liulilittle2 小时前
eBPF tc prog
服务器·网络·c++·网络协议·tcp/ip·性能·perf
cui_ruicheng2 小时前
C++ 新特性(下):可变参数模板与 STL 扩展机制
开发语言·c++·c++11
拾荒的路由2 小时前
HOT100DAY9记录用
数据结构·算法·leetcode
|_⊙2 小时前
C++ 多态
c++
寒月小酒3 小时前
3.26 OJ
数据结构·算法
福楠3 小时前
现代C++ | 智能指针
c语言·开发语言·c++
汉克老师3 小时前
GESP5级C++考试语法知识(十二、递归算法(二))
c++·算法·记忆化搜索·时间复杂度·递归算法·gesp5级·gesp五级
旺仔.2913 小时前
顺序容器:Array 数组 详解
c++
qq_392807953 小时前
Qt 注册 C++ 给 QML 调用的几种方式
数据库·c++·qt