C++ 常用数据结构速查:vector、stack、queue、list、树、图、哈希表等声明与核心操作

万能头文件

cpp 复制代码
#include <bits/stdc++.h>

using namespace std;

bits/stdc++.h 包含了绝大多数标准库头文件,在算法竞赛和面试手撕代码时能显著节省书写时间。

注意:这是 GCC 编译器特有的非标准头文件,在 MSVC 或某些严格环境下可能无法使用,但在绝大多数在线笔试平台(牛客、LeetCode C++ 环境通常支持 GCC)中可正常工作。

一、动态数组 vector

声明:

cpp 复制代码
vector<int> v;                    // 空数组

vector<int> v(10);                // 10 个 0

vector<int> v(10, 5);             // 10 个 5

vector<vector<int>> matrix(5, vector<int>(5, 0));  // 5x5 二维数组

vector<int> v = {1, 2, 3};       // 列表初始化

常用操作:

操作 代码 复杂度
尾部添加 v.push_back(x) 均摊 O(1)
尾部删除 v.pop_back() O(1)
访问元素 vi 或 v.at(i) O(1)
首尾迭代器 v.begin(), v.end() O(1)
大小/空判断 v.size(), v.empty() O(1)
指定位置插入 v.insert(v.begin()+i, x) O(n)
指定位置删除 v.erase(v.begin()+i) O(n)
调整大小 v.resize(n) O(n)
排序 sort(v.begin(), v.end()) O(n log n)
二分查找(有序) binary_search(v.begin(), v.end(), x) O(log n)

常用技巧:

cpp 复制代码
// 去重(需先排序)

sort(v.begin(), v.end());

v.erase(unique(v.begin(), v.end()), v.end());



// 二维数组遍历

for (auto& row : matrix) {

    for (int x : row) cout << x << " ";

}

二、栈 stack

声明:

cpp 复制代码
stack<int> s;

常用操作:

操作 代码
入栈 s.push(x)
出栈 s.pop()(无返回值)
取栈顶 s.top()
判空 s.empty()
大小 s.size()

栈适用于括号匹配、逆波兰表达式求值、单调栈等场景。底层默认使用 deque,但是相对来说算是细节,一般不需要关心 。

三、队列 queue

声明:

cpp 复制代码
queue<int> q;

常用操作:

操作 代码
入队 q.push(x)
出队 q.pop()(无返回值)
取队首 q.front()
取队尾 q.back()
判空/大小 q.empty(), q.size()

BFS 的标配容器。如果需要双端操作,使用 deque:

cpp 复制代码
deque<int> dq;

dq.push_back(x);   // 尾插

dq.push_front(x);  // 头插 O(1)

dq.pop_back();

dq.pop_front();

四、优先队列 priority_queue

声明:

cpp 复制代码
priority_queue<int> pq;                                    // 大顶堆(默认)

priority_queue<int, vector<int>, greater<int>> min_pq;     // 小顶堆

常用操作:

操作 代码
插入 pq.push(x)
删除堆顶 pq.pop()
取堆顶 pq.top()
判空/大小 pq.empty(), pq.size()

自定义类型:

cpp 复制代码
struct Node { int dist; int id; };

struct cmp {

    bool operator()(Node& a, Node& b) {

        return a.dist > b.dist;  // 距离小的优先级高(小顶堆)

    }

};

priority_queue<Node, vector<Node>, cmp> pq;

适用于 Dijkstra、Top K 问题、任务调度等 。

五、链表 list

声明:

cpp 复制代码
list<int> lst;

常用操作:

操作 代码
头/尾插入 lst.push_front(x), lst.push_back(x)
头/尾删除 lst.pop_front(), lst.pop_back()
指定位置插入 lst.insert(it, x)
删除元素 lst.erase(it)
排序 lst.sort()
判空/大小 lst.empty(), lst.size()

list 是双向链表,不支持随机访问 \[\]。插入删除 O(1)(已知迭代器位置),但查找 O(n) 。

手撕链表通常需要手写节点结构,因为面试官考察的是指针操作:

cpp 复制代码
struct ListNode {

    int val;

    ListNode* next;

    ListNode(int x) : val(x), next(nullptr) {}

};

六、树(set / map:平衡二叉搜索树)

STL 没有直接提供"树"容器,但 set 和 map 底层是红黑树(平衡 BST),提供 O(log n) 的有序操作。

set(有序集合,去重)

声明:

cpp 复制代码
set<int> s;

常用操作:

cpp 复制代码
s.insert(x);           // 插入 O(log n)

s.erase(x);            // 删除

s.find(x);             // 查找,返回迭代器

s.count(x);            // 存在返回 1

s.lower_bound(x);      // >= x 的第一个元素

s.upper_bound(x);      // > x 的第一个元素

map(有序键值对)

声明:

cpp 复制代码
map<string, int> mp;

常用操作:

cpp 复制代码
mp["key"] = 1;              // 插入/修改

mp.insert({"key", 1});

mp.erase("key");

mp.find("key");             // 返回迭代器

mp.count("key");            // 判断存在

for (auto& [k, v] : mp)     // C++17 结构化绑定遍历

    cout << k << ": " << v;

手写二叉树节点

cpp 复制代码
struct TreeNode {

    int val;

    TreeNode *left, *right;

    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}

};

七、哈希表 unordered_map / unordered_set

声明:

cpp 复制代码
unordered_map<int, int> hashmap;    // 键值对

unordered_set<int> hashset;         // 集合

常用操作(与 map/set 类似,但无序):

操作 代码 平均复杂度
插入/修改 mpkey = val O(1)
查找 mp.find(key) O(1)
存在判断 mp.count(key) O(1)
删除 mp.erase(key) O(1)

关键区别:

unordered_map 平均 O(1),但最坏 O(n)(哈希冲突),且无序

map 稳定 O(log n),有序,可用 lower_bound

面试中涉及"查找/计数/去重"且不要求顺序时,优先使用 unordered_map 或 unordered_set 。

八、图(邻接表表示)

C++ STL 没有内置图容器,通常用 vector 模拟邻接表:

cpp 复制代码
// 邻接表:g[u] 存储 u 的所有邻居

vector<vector<int>> g(n + 1);


// 添加有向边 u -> v

g[u].push_back(v);


// 添加无向边

g[u].push_back(v);

g[v].push_back(u);


// 带权图:pair<邻点, 权重>

vector<vector<pair<int, int>>> wg(n + 1);

wg[u].push_back({v, w});

BFS 遍历模板:

cpp 复制代码
queue<int> q;

vector<bool> visited(n + 1, false);

q.push(start);

visited[start] = true;

while (!q.empty()) {

    int u = q.front(); q.pop();

    for (int v : g[u]) {

        if (!visited[v]) {

            visited[v] = true;

            q.push(v);

        }

    }

}

DFS 递归模板:

cpp 复制代码
void dfs(int u, vector<vector<int>>& g, vector<bool>& visited) {

    visited[u] = true;

    for (int v : g[u]) {

        if (!visited[v]) dfs(v, g, visited);

    }

}

九、C++17 结构化绑定(强烈推荐)

在遍历 map 或 vector<pair> 时,结构化绑定可以大幅简化代码:

cpp 复制代码
// 以前

for (auto& it : mp) {

    cout << it.first << " " << it.second;

}



// C++17

for (auto& [key, value] : mp) {

    cout << key << " " << value;

}

配合 auto&& 使用可以避免不必要的拷贝。

相关推荐
别动我齐刘海2 小时前
实时控制学习2
linux·c++·人工智能·学习·算法
hetao17338374 小时前
校内场-提高组 ZYZSC-S-Round 2
c++·算法
hetao17338374 小时前
2026-10-14 hetao1733837 的刷题记录
c++·算法
浅念-5 小时前
动态规划:线性DP——多状态DP与子数组专题笔记
c++·笔记·算法·leetcode·职场和发展·动态规划·力扣
爱读书的小胖6 小时前
LeetCode 27. 移除元素(C)解题分析
数据结构·算法
爱读书的小胖7 小时前
Codewars: A Brave New Wordle(C)解题分析
c语言·数据结构·算法
Escalating_xu7 小时前
【数据结构】顺序表的应用:动态通讯录项目与双指针经典算法
c语言·数据结构·算法
StarRocks_labs7 小时前
StarRocks 接入 Paimon C++:让湖上查询进入原生执行链路
starrocks·c++·sql·jni·paimon·auto·湖上查询
垆边人似月.8 小时前
华为题:字符串中最长连续数字串
开发语言·c++·算法