
在 C++ 编程中,算法是处理数据的核心工具。传统算法往往针对特定数据类型设计,缺乏复用性;而泛型算法(Generic Algorithms)通过模板技术实现类型无关化,可适配多种容器与数据类型,极大提升代码通用性与效率。
泛型算法是一类基于模板的通用函数,不依赖具体数据类型,而是通过迭代器(Iterator)操作容器元素。例如,std::find用于查找元素,既可作用于vector<int>,也能适配list<string>,只需传递对应容器的迭代器即可。具有以下显著特点:
STL算法可分为六大类:
分类 | 代表算法 | 特性说明 |
|---|---|---|
非修改序列算法 | find, count, for_each | 不改变容器内容 |
修改序列算法 | copy, replace, reverse | 直接修改容器元素 |
排序相关算法 | sort, stable_sort | 元素排序和重组 |
数值算法 | accumulate, inner_product | 数学计算操作 |
集合算法 | set_union, set_difference | 集合运算 |
堆算法 | make_heap, push_heap | 堆结构操作 |
泛型算法是 C++ 标准模板库(STL)的重要组成部分,与容器紧密协作:
图示:泛型算法、容器与迭代器的协作关系

C++ 定义了 5 类迭代器,算法依需求选用:
类型 | 功能特性 | 典型应用算法 |
|---|---|---|
输入迭代器 | 单向读取(*it、++it) | std::find、std::for_each |
输出迭代器 | 单向写入(*it = value) | std::copy |
前向迭代器 | 单向读写(输入 + 输出功能结合) | std::list专用算法 |
双向迭代器 | 双向读写(--it支持逆向) | std::reverse |
随机访问迭代器 | 随机定位(it[n]、it += n) | std::sort、std::binary_search |
示例:使用std::back_inserter向vector插入元素
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v;
auto inserter = back_inserter(v); // 创建插入迭代器
*inserter = 10; // 等效于v.push_back(10)
*inserter = 20;
for (int x : v) cout << x << " "; // 输出: 10 20
return 0;
}
示例:统计容器中偶数个数
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void doubleValue(int& x) { x *= 2; }
int main() {
vector<int> v = {1, 2, 3};
std::for_each(v.begin(), v.end(), doubleValue);
for (int x : v) cout << x << " "; // 输出: 2 4 6
return 0;
}
示例:将容器元素翻倍
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void doubleValue(int& x) { x *= 2; }
int main() {
vector<int> v = {1, 2, 3};
std::for_each(v.begin(), v.end(), doubleValue);
for (int x : v) cout << x << " "; // 输出: 2 4 6
return 0;
}
示例:自定义比较函数排序结构体
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Point {
int x, y;
};
bool compareByX(const Point& a, const Point& b) {
return a.x < b.x;
}
int main() {
vector<Point> points = {{3, 4}, {1, 2}, {2, 3}};
std::sort(points.begin(), points.end(), compareByX);
for (const auto& p : points) {
cout << "(" << p.x << ", " << p.y << ") ";
}
return 0;
}
通过 lambda 表达式或函数对象定制算法逻辑,如std::sort的比较规则、std::find_if的查找条件。
Ranges 库简化算法调用,支持惰性求值(延迟计算)。例如:
#include <iostream>
#include <ranges>
#include <vector>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5};
auto result = v | views::filter([](int x) { return x % 2 == 0; }) | views::transform([](int x) { return x * 2; });
for (int x : result) cout << x << " "; // 输出: 4 8
return 0;
}// 读取数据 -> 过滤 -> 变换 -> 统计 -> 输出
ifstream input("data.txt");
vector<Data> raw_data;
// 读取阶段
Data temp;
while (input >> temp) {
raw_data.push_back(temp);
}
// 过滤阶段
auto new_end = std::remove_if(raw_data.begin(), raw_data.end(),
[](const Data& d){ return d.value < 0; });
raw_data.erase(new_end, raw_data.end());
// 变换阶段
std::transform(raw_data.begin(), raw_data.end(), raw_data.begin(),
[](Data d){ d.value *= 2; return d; });
// 统计阶段
int count = std::count_if(raw_data.begin(), raw_data.end(),
[](const Data& d){ return d.category == "A"; });
// 输出阶段
std::for_each(raw_data.begin(), raw_data.end(),
[](const Data& d){ cout << d << endl; });class GameObject {
public:
bool isActive() const { return m_active; }
void update() { /* ... */ }
private:
bool m_active = true;
};
vector<GameObject> objects;
// 批量更新活跃对象
std::for_each(objects.begin(), objects.end(),
[](GameObject& obj){ if (obj.isActive()) obj.update(); });
// 移除所有非活跃对象
auto new_end = std::remove_if(objects.begin(), objects.end(),
[](const GameObject& obj){ return !obj.isActive(); });
objects.erase(new_end, objects.end());vector<Event> event_queue;
// 处理鼠标事件
auto it = std::remove_if(event_queue.begin(), event_queue.end(),
[](const Event& e){
return e.type != MOUSE_MOVE &&
e.type != MOUSE_CLICK;
});
event_queue.erase(it, event_queue.end());
// 分派事件
std::for_each(event_queue.begin(), event_queue.end(),
[](const Event& e){
switch(e.type) {
case MOUSE_MOVE: handle_move(e); break;
case MOUSE_CLICK: handle_click(e); break;
}
});例如:对list使用std::sort会编译错误,应改用list::sort。
误用std::remove
vector<int> v = {1, 2, 2, 3};
v.erase(std::remove(v.begin(), v.end(), 2), v.end()); // 移除所有值为2的元素std::remove仅逻辑删除(移动元素),需配合erase真正释放空间:
泛型算法通过模板与迭代器的结合,实现了高度抽象与复用,是 C++ 高效编程的基石。从基础查找排序到复杂自定义逻辑,掌握算法的使用场景与迭代器适配技巧,能大幅提升代码质量。结合 C++ 新特性(如 Ranges 库),更可进一步简化开发流程。后续可深入探索分区算法、堆操作等进阶内容,解锁更多编程可能。
using声明在模板编程中有着重要应用,如定义模板类型别名等。