std::ranges::mergestd::mergestd::inplace_merge
- 手机
- 2025-09-04 12:39:02

std::ranges::merge
是 C++20 引入的算法,用于将两个已排序的范围合并为一个有序序列。
基本功能 输入:两个已排序的范围(升序或降序,需一致)。输出:将两个范围合并后的结果写入目标范围,保持有序。稳定性:相等元素的相对顺序会被保留(稳定合并)。Defined in header <algorithm>
Call signature
template< std::input_iterator I1, std::sentinel_for<I1> S1,std::input_iterator I2, std::sentinel_for<I2> S2, std::weakly_incrementable O, class Comp = ranges::less, class Proj1 = std::identity, class Proj2 = std::identity > requires std::mergeable<I1, I2, O, Comp, Proj1, Proj2> constexpr merge_result<I1, I2, O> merge( I1 first1, S1 last1, I2 first2, S2 last2, O result, Comp comp = {},
Proj1 proj1 = {}, Proj2 proj2 = {} );(1)(since C++20)template< ranges::input_range R1, ranges::input_range R2,std::weakly_incrementable O, class Comp = ranges::less, class Proj1 = std::identity, class Proj2 = std::identity > requires std::mergeable<ranges::iterator_t<R1>, ranges::iterator_t<R2>, O, Comp, Proj1, Proj2> constexpr merge_result<ranges::borrowed_iterator_t<R1>, ranges::borrowed_iterator_t<R2>, O> merge( R1&& r1, R2&& r2, O result, Comp comp = {},
Proj1 proj1 = {}, Proj2 proj2 = {} ); 参数: first1, last1:第一个输入范围的起止迭代器。first2, last2:第二个输入范围的起止迭代器。result:目标范围的起始迭代器。comp:比较函数(默认为 std::ranges::less)。proj1, proj2:对输入元素的投影(默认为恒等投影 std::identity)。示例代码 #include <algorithm> #include <vector> #include <iostream> #include <iterator> int main() { std::vector<int> v1 = {1, 3, 5, 7}; std::vector<int> v2 = {2, 4, 6, 8}; std::vector<int> result; // 确保目标容器有足够空间 result.resize(v1.size() + v2.size()); // 合并 v1 和 v2 到 result std::ranges::merge(v1, v2, result.begin()); // 输出结果 for (int x : result) { std::cout << x << " "; } // 输出:1 2 3 4 5 6 7 8 }
详细说明
输入范围必须有序:
若输入未排序,结果可能无序。排序方向需一致(均升序或均降序)。目标空间要求:
目标范围必须有足够空间容纳 size(v1) + size(v2) 个元素。可使用 resize() 或预先分配空间。自定义比较和投影:
支持自定义比较函数(如降序合并)。投影允许对元素进行变换后再比较。 std::merge用于将两个已排序的范围合并为一个新的已排序范围。它不会修改输入范围,而是将结果存储到另一个范围中。
Defined in header <algorithm>
template< class InputIt1, class InputIt2, class OutputIt >OutputIt merge( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
OutputIt d_first );(1)(constexpr since C++20)template< class ExecutionPolicy,class ForwardIt1, class ForwardIt2, class ForwardIt3 > ForwardIt3 merge( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2,
ForwardIt3 d_first );(2)(since C++17)template< class InputIt1, class InputIt2,class OutputIt, class Compare > OutputIt merge( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
OutputIt d_first, Compare comp );(3)(constexpr since C++20)template< class ExecutionPolicy,class ForwardIt1, class ForwardIt2, class ForwardIt3, class Compare > ForwardIt3 merge( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2,
ForwardIt3 d_first, Compare comp );参数说明
first1, last1: 第一个输入范围的起始和结束迭代器。
first2, last2: 第二个输入范围的起始和结束迭代器。
d_first: 目标范围的起始迭代器,用于存储合并后的结果。
comp: 可选的比较函数对象,用于定义元素的顺序。默认是 std::less。
返回值返回目标范围的结束迭代器,指向最后一个写入元素的下一个位置。
示例 1:基本用法
以下是一个简单的示例,展示如何使用 std::merge 将两个已排序的数组合并为一个新的已排序数组。
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v1 = {1, 3, 5, 7}; // 已排序 std::vector<int> v2 = {2, 4, 6, 8}; // 已排序 std::vector<int> result(v1.size() + v2.size()); // 目标范围 // 合并 v1 和 v2 到 result std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin()); // 输出结果 std::cout << "Merged result: "; for (int i : result) { std::cout << i << " "; } std::cout << "\n"; return 0; }输出
Merged result: 1 2 3 4 5 6 7 8 示例 2:使用自定义比较函数std::merge 允许你提供一个自定义的比较函数来控制排序的顺序。例如,如果你想按降序合并两个已排序的范围。
排序方式需与 comp 一致
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v1 = {7, 5, 3, 1}; // 已排序(降序) std::vector<int> v2 = {8, 6, 4, 2}; // 已排序(降序) std::vector<int> result(v1.size() + v2.size()); // 目标范围 // 合并 v1 和 v2 到 result,按降序排列 std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin(), std::greater<int>()); // 输出结果 std::cout << "Merged result (descending): "; for (int i : result) { std::cout << i << " "; } std::cout << "\n"; return 0; }输出
Merged result (descending): 8 7 6 5 4 3 2 1解释
v1 和 v2 是两个已按降序排序的向量。
std::merge 使用 std::greater<int> 作为比较函数,将两个向量合并为一个新的降序排序的向量 result。
示例 4:合并到原始范围如果你希望使用 std::merge将结果直接存储到原始范围中,可以先将结果存储到一个临时范围,然后再复制回原始范围。
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v1 = {1, 3, 5, 7}; // 已排序 std::vector<int> v2 = {2, 4, 6, 8}; // 已排序 std::vector<int> result(v1.size() + v2.size()); // 目标范围 // 合并 v1 和 v2 到 result std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin()); // 将结果复制回 v1 v1 = result; // 输出结果 std::cout << "Merged result in v1: "; for (int i : v1) { std::cout << i << " "; } std::cout << "\n"; return 0; } 输出复制
Merged result in v1: 1 2 3 4 5 6 7 8 解释std::merge 将 v1 和 v2 合并到 result。
然后将 result 复制回 v1,使 v1 包含合并后的结果。
下列这几个容器在C++17时加入了自己的merge接口:
std::map std::set std::multimap std::multiset std::unordered_map std::unordered_set std::unordered_multimap std::unordered_multiset
std::vector 和 std::array是没有merge的,需要通过std::merge库函数来merge。
如果你希望将结果直接存储到原始范围中,可以使用 std::inplace_merge。
std::inplace_merge用于将两个已排序的连续序列合并为一个有序序列,且合并过程直接在原序列中进行(不额外分配内存)。它通常用于归并排序的实现。
Defined in header <algorithm>
template< class BidirIt > void inplace_merge( BidirIt first, BidirIt middle, BidirIt last );
(1)(constexpr since C++26)template< class ExecutionPolicy, class BidirIt >void inplace_merge( ExecutionPolicy&& policy,
BidirIt first, BidirIt middle, BidirIt last );(2)(since C++17)template< class BidirIt, class Compare >void inplace_merge( BidirIt first, BidirIt middle, BidirIt last,
Compare comp );(3)(constexpr since C++26)template< class ExecutionPolicy, class BidirIt, class Compare >void inplace_merge( ExecutionPolicy&& policy, BidirIt first, BidirIt middle, BidirIt last,
Compare comp ); 参数: first:第一个有序序列的起始迭代器。middle:第一个有序序列的结束位置,同时也是第二个有序序列的起始位置。last:第二个有序序列的结束位置。comp:自定义比较函数(可选,默认使用 < 运算符)。 关键点 前提条件: [first, middle) 和 [middle, last) 必须是已排序的序列。排序方式需与 comp 一致(若提供)。 时间复杂度: 如果额外内存足够,复杂度为 O(N)(N 为元素总数)。否则为 O(N log N)。 原地操作:合并后的结果直接存储在 [first, last) 中。示例 示例 1:合并两个有序子数组 #include <algorithm> #include <vector> #include <iostream> int main() { std::vector<int> v = {1, 3, 5, 2, 4, 6}; // 前3个和后3个已分别排序 std::inplace_merge(v.begin(), v.begin() + 3, v.end()); for (int x : v) { std::cout << x << " "; } }
输出:
1 2 3 4 5 6
示例 2:自定义比较函数 #include <algorithm> #include <vector> #include <iostream> bool compare(int a, int b) { return a > b; // 降序排序 } int main() { std::vector<int> v = {5, 3, 1, 6, 4, 2}; // 前3个和后3个已按降序排序 std::inplace_merge(v.begin(), v.begin() + 3, v.end(), compare); for (int x : v) { std::cout << x << " "; } // 输出:6 5 4 3 2 1 } 应用场景 归并排序:在递归合并步骤中使用 std::inplace_merge。合并相邻有序区间:例如处理分段排序后的数据。 注意事项 确保输入区间已按指定顺序排序。若对性能要求高,需关注内存分配的影响(尽量保证有足够内存)。 std::ranges::inplace_mergestd::ranges::mergestd::mergestd::inplace_merge由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“std::ranges::mergestd::mergestd::inplace_merge”