std::inplace_merge
来自cppreference.com
| 在标头 <algorithm> 定义
|
||
| (1) | (C++26 起为 constexpr) | |
| |
(2) | (C++17 起) |
| (3) | (C++26 起为 constexpr) | |
| |
(4) | (C++17 起) |
将两个相继的有序范围 [first, middle) 和 [middle, last) 归并为一个有序范围 [first, last)。
3) 如果
[first, middle) 或 [middle, last) 没有按 comp 排序,那么行为未定义。2,4) 同 (1,3),但按照
policy 执行。 这些重载只有在满足以下所有条件时才会参与重载决议:
|
|
(C++20 前) |
|
|
(C++20 起) |
此合并函数是稳定的,意思是对于两个原范围中的等价元素,来自第一范围的元素(保持原来的顺序)先于来自第二范围的元素(保持原来的顺序)。
如果满足以下任意条件,那么行为未定义:
[first,middle)或[middle,last)不是有效范围。
|
(C++11 前) |
|
(C++11 起) |
参数
| first | - | 第一个有序范围的起始 |
| middle | - | 第一个有序范围的结尾及第二个有序范围的起始 |
| last | - | 第二个有序范围的结尾 |
| policy | - | 所用的执行策略 |
| comp | - | 比较函数对象(即满足比较 (Compare) 概念的对象),在第一参数小于(即先 序于)第二参数时返回 true。比较函数的签名应等价于如下:
虽然签名不必有 |
| 类型要求 | ||
-BidirIt 必须满足老式双向迭代器 (LegacyBidirectionalIterator) 。
| ||
-Compare 必须满足比较 (Compare) 。
| ||
复杂度
给定 N 为 std::distance(first, last):
1) 在额外内存足够时应用 N-1 次
operator<(C++20 前)std::less{}(C++20 起) 进行比较,否则应用 O(N⋅log(N)) 次。2) 应用 O(N⋅log(N)) 次
operator<(C++20 前)std::less{}(C++20 起) 进行比较。3) 在额外内存足够时最多应用 N-1 次比较函数
comp,否则应用 O(N⋅log(N)) 次。4) 应用 O(N⋅log(N)) 次比较函数
comp。异常
拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:
- 如果作为算法一部分调用的函数的执行抛出异常,且
ExecutionPolicy是标准策略之一,那么调用 std::terminate。对于任何其他ExecutionPolicy,行为由实现定义。 - 如果算法无法分配内存,那么抛出 std::bad_alloc。
可能的实现
注解
此函数试图分配临时缓冲区。如果分配失败,那么就会选择较低效的算法。
| 功能特性测试宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_lib_constexpr_algorithms |
202306L |
(C++26) | constexpr 原地归并 (1), (3)
|
示例
下列代码是归并排序的一种实现。
运行此代码
#include <algorithm>
#include <iostream>
#include <vector>
template<class Iter>
void merge_sort(Iter first, Iter last)
{
if (last - first > 1)
{
Iter middle = first + (last - first) / 2;
merge_sort(first, middle);
merge_sort(middle, last);
std::inplace_merge(first, middle, last);
}
}
int main()
{
std::vector<int> v{8, 2, -2, 0, 11, 11, 1, 7, 3};
merge_sort(v.begin(), v.end());
for (const auto& n : v)
std::cout << n << ' ';
std::cout << '\n';
}
输出:
-2 0 1 2 3 7 8 11 11
参阅
| 合并两个有序范围 (函数模板) | |
| 将范围按升序排序 (函数模板) | |
| 将范围中元素排序,同时保持相等元之间的顺序 (函数模板) | |
(C++20) |
就地合并两个有序范围 (算法函数对象) |