作为一名经历过考研复试的C++开发者,我深知数据结构与算法在机试环节的重要性。市面上虽然有不少算法题库,但专门针对考研复试场景、用C++实现且涵盖完整代码示例的资源却相当匮乏。这正是我整理这份代码大全的初衷——为即将面临机试的同学们提供一本"开箱即用"的实战手册。
这份大全的特点在于:
提示:考研机试通常限制C++版本,建议使用兼容性更好的C++11标准,避免使用C++17/20特有的语法糖。
我将内容划分为三个层级:
每个算法单元包含:
cpp复制// 标准实现(无冗余代码)
// 输入输出示例
// 时间复杂度分析
例如快速排序的实现:
cpp复制int partition(vector<int>& arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
swap(arr[i], arr[j]);
}
}
swap(arr[i+1], arr[high]);
return i+1;
}
void quickSort(vector<int>& arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi-1);
quickSort(arr, pi+1, high);
}
}
针对机试特点特别加入:
考研机试往往对内存有严格限制,因此需要:
cpp复制// 使用reserve预分配vector容量
vector<int> v;
v.reserve(1e6);
// 优先使用emplace_back减少拷贝
vector<pair<int,int>> v;
v.emplace_back(1, 2); // 优于push_back(make_pair(1,2))
以Dijkstra算法为例,给出最简实现:
cpp复制void dijkstra(vector<vector<pair<int,int>>>& graph, int start) {
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;
vector<int> dist(graph.size(), INT_MAX);
pq.emplace(0, start);
dist[start] = 0;
while (!pq.empty()) {
auto [d, u] = pq.top(); pq.pop();
if (d > dist[u]) continue;
for (auto [v, w] : graph[u]) {
if (dist[v] > dist[u] + w) {
dist[v] = dist[u] + w;
pq.emplace(dist[v], v);
}
}
}
}
针对机试大数据量场景:
cpp复制// 关闭同步流(慎用,不能再混用C风格IO)
ios::sync_with_stdio(false);
cin.tie(nullptr);
// 快速读取整数
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
cpp复制// 01背包
vector<int> dp(W+1);
for (int i = 0; i < N; i++) {
for (int j = W; j >= weight[i]; j--) {
dp[j] = max(dp[j], dp[j-weight[i]] + value[i]);
}
}
// 完全背包(正序循环)
for (int j = weight[i]; j <= W; j++) {
dp[j] = max(dp[j], dp[j-weight[i]] + value[i]);
}
cpp复制// 旅行商问题
int dp[1<<n][n];
memset(dp, 0x3f, sizeof(dp));
dp[1][0] = 0;
for (int mask = 1; mask < (1<<n); mask++) {
for (int u = 0; u < n; u++) {
if (!(mask & (1<<u))) continue;
for (int v = 0; v < n; v++) {
if (mask & (1<<v)) continue;
dp[mask|(1<<v)][v] = min(dp[mask|(1<<v)][v],
dp[mask][u] + graph[u][v]);
}
}
}
cpp复制vector<int> parent, rank;
int find(int x) {
return parent[x] == x ? x : parent[x] = find(parent[x]);
}
void unite(int x, int y) {
x = find(x), y = find(y);
if (x == y) return;
if (rank[x] < rank[y]) {
parent[x] = y;
} else {
parent[y] = x;
if (rank[x] == rank[y]) rank[x]++;
}
}
cpp复制void tarjan(int u) {
dfn[u] = low[u] = ++idx;
stk.push(u); inStack[u] = true;
for (int v : graph[u]) {
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (inStack[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if (dfn[u] == low[u]) {
int v;
do {
v = stk.top(); stk.pop();
inStack[v] = false;
scc[v] = cnt;
} while (v != u);
cnt++;
}
}
边界条件测试:
内存泄漏检测:
cpp复制// 在本地调试时可添加
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
cpp复制// 传引用而非值
void process(const vector<int>& nums);
// 使用move语义
vector<int> createLargeVector() {
vector<int> v(1e6);
return v; // 编译器会自动优化为move
}
| 场景 | 推荐容器 | 时间复杂度 |
|---|---|---|
| 频繁随机访问 | vector | O(1) |
| 频繁插入删除 | list | O(1) |
| 快速查找 | unordered_set | O(1) |
| 有序数据 | set | O(log n) |
cpp复制// 错误:迭代器失效
for (auto it = vec.begin(); it != vec.end(); ) {
if (*it % 2 == 0) {
vec.erase(it); // 错误!
it = vec.erase(it); // 正确
} else {
++it;
}
}
cpp复制// 错误:可能溢出
int mid = (low + high) / 2;
// 正确:安全写法
int mid = low + (high - low) / 2;
cpp复制TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (!root || root == p || root == q) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if (left && right) return root;
return left ? left : right;
}
cpp复制vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> dq;
vector<int> res;
for (int i = 0; i < nums.size(); i++) {
if (!dq.empty() && dq.front() == i - k) {
dq.pop_front();
}
while (!dq.empty() && nums[dq.back()] < nums[i]) {
dq.pop_back();
}
dq.push_back(i);
if (i >= k - 1) {
res.push_back(nums[dq.front()]);
}
}
return res;
}
推荐在线判题平台:
进阶学习路线:
代码规范建议:
在实际机试中,建议先写伪代码理清思路,再转化为具体实现。遇到难题时,优先保证基础用例的正确性,再考虑优化效率。