C++ 标准模板库(STL)提供了丰富的算法库(定义在<algorithm>头文件中),这些算法多为通用函数模板,可配合容器和迭代器高效操作数据。
1、非修改序列算法
这些算法不会改变它们所操作的容器中的元素。
1.1 find 和 find_if
find(begin, end, value):查找第一个等于value的元素,返回迭代器(未找到返回end)。find_if(begin, end, predicate):查找第一个满足谓词的元素。find_end(begin, end, sub_begin, sub_end):查找子序列最后一次出现的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1.2 count 和 count_if
count(begin, end, value):统计等于value的元素个数。count_if(begin, end, predicate):统计满足谓词(predicate)的元素个数。
1 2 3 4 5 |
|
1.3 for_each
对范围内的每个元素应用一个函数
1 2 3 4 5 |
|
1.4 equal 与 mismatch
equal(b1, e1, b2):判断两个范围[b1,e1)和[b2, b2+(e1-b1))是否相等。mismatch(b1, e1, b2):返回两个范围中第一个不相等元素的迭代器对(pair)。
1 2 3 4 5 6 7 8 9 10 11 |
|
1.5 all_of, any_of, none_of
检查范围内元素是否全部、存在或没有满足条件的
1 2 3 4 5 6 7 8 9 10 |
|
2、修改序列算法
这些算法会修改它们所操作的容器中的元素。
2.1 copy 和 copy_if
copy(begin, end, dest):将[begin, end)中的元素复制到dest开始的位置。copy_if(begin, end, dest, predicate):复制满足谓词的元素到dest。
1 2 3 4 5 6 7 8 9 |
|
注意:back_inserter(dest)会自动调用push_back,无需提前分配空间。
2.2 transform
对范围内的每个元素应用一个函数,并将结果存储在另一个范围内
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
2.3 replace、replace_if与 replace_copy
replace(begin, end, old_val, new_val):将所有old_val替换为new_val。replace_if(begin, end, predicate, new_val):替换满足谓词的元素。replace_copy(begin, end, dest, old_val, new_val):复制时替换元素(不修改原容器)。
1 2 3 4 5 6 7 8 9 10 |
|
2.4 remove、remove_if 与 erase
remove(begin, end, value):将等于value的元素 “移动” 到容器末尾,返回新的逻辑尾迭代器(不实际删除元素,需配合erase)。remove_if(begin, end, predicate):移动满足谓词的元素到末尾。
1 2 3 4 5 6 7 8 9 10 |
|
2.5 unique
移除范围内连续的重复元素,返回新的逻辑结尾迭代器。通常与erase结合使用。
1 2 3 |
|
2.6 reverse
反转范围内的元素顺序
1 2 |
|
2.7 rotate
旋转范围内的元素,使中间元素成为新的第一个元素
1 2 |
|
2.8 shuffle
随机重排范围内的元素(需要C++11或更高版本)
1 2 3 4 5 6 |
|
3、排序和相关算法
3.1 sort、stable_sort 与 partial_sort
sort(begin, end):对元素进行快速排序(不稳定,平均时间复杂度 O (n log n))。stable_sort(begin, end):稳定排序(相等元素相对位置不变)。partial_sort(begin, mid, end):部分排序,使[begin, mid)为整个范围中最小的元素并排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
3.2 nth_element
重新排列范围,使得指定位置的元素等于排序后的元素,并且左边的元素都不大于它,右边的元素都不小于它
1 2 3 4 |
|
3.3 binary_search、lower_bound、upper_bound
需在已排序的容器上使用
binary_search(begin, end, value):判断value是否存在(返回bool)。lower_bound(begin, end, value):返回第一个不小于value的元素迭代器。upper_bound(begin, end, value):返回第一个大于value的元素迭代器。
1 2 3 4 5 6 7 8 9 |
|
3.4 merge
合并两个已排序的范围到新容器(保持排序)
1 2 3 4 5 |
|
4、堆算法
STL提供了将范围作为堆来操作的算法,包括make_heap,push_heap,pop_heap,sort_heap等。
1 2 3 4 5 6 7 8 |
|
5、最小/最大值算法
5.1 min 和 max
返回两个值或初始化列表中的最小/最大值
1 2 3 4 5 |
|
5.2 min_element 和 max_element
返回范围内的最小/最大元素的迭代器
1 2 3 |
|
5.3 minmax_element (C++11)
同时返回范围内的最小和最大元素的迭代器
1 2 3 |
|
6、数值算法(在<numeric>中)
6.1 accumulate
计算范围内元素的累加和(或自定义操作)
1 2 3 4 |
|
6.2 inner_product
计算两个范围的内积(或自定义操作)
1 2 3 |
|
6.3 iota
用连续递增的值填充范围
1 2 |
|
6.4 partial_sum
计算部分和,将结果存储在目标范围内
1 2 3 |
|
6.5 adjacent_difference
计算相邻元素的差值,将结果存储在目标范围内
1 2 3 |
|
7、其他
7.1 generate
用生成函数填充范围
1 2 3 4 5 |
|
7.2 generate_n
用生成函数填充范围的开始n个元素
1 2 3 4 5 |
|
7.3 includes
检查一个排序范围是否包含另一个排序范围的所有元素
1 2 3 |
|
7.3 set_union, set_intersection, set_difference, set_symmetric_difference
执行集合操作:并集、交集、差集和对称差集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
8、常见问题
sort与stable_sort的区别?sort采用快速排序(实际是 introsort 算法),不稳定(相等元素的相对位置可能改变),平均时间复杂度 O (n log n)。stable_sort采用归并排序,稳定(相等元素相对位置不变),时间复杂度 O (n log n),但空间开销略大。