Files
2025-10-25 03:02:53 +03:00

281 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[alg.merge]
# 26 Algorithms library [[algorithms]](./#algorithms)
## 26.8 Sorting and related operations [[alg.sorting]](alg.sorting#alg.merge)
### 26.8.6 Merge [alg.merge]
[🔗](#lib:merge)
`template<class InputIterator1, class InputIterator2,
class OutputIterator>
constexpr OutputIterator
merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
class ForwardIterator>
ForwardIterator
merge(ExecutionPolicy&& exec,
ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
ForwardIterator result);
template<class InputIterator1, class InputIterator2,
class OutputIterator, class Compare>
constexpr OutputIterator
merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result, Compare comp);
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2,
class ForwardIterator, class Compare>
ForwardIterator
merge(ExecutionPolicy&& exec,
ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
ForwardIterator result, Compare comp);
template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I1, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I1> S1, [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I2> S2,
[weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") O, class Comp = ranges::less, class Proj1 = identity,
class Proj2 = identity>
requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7Concept mergeable[alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
constexpr ranges::merge_result<I1, I2, O>
ranges::merge(I1 first1, S1 last1, I2 first2, S2 last2, O result,
Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R1, [input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R2, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4Concept weakly_­incrementable[iterator.concept.winc]") O, class Comp = ranges::less,
class Proj1 = identity, class Proj2 = identity>
requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7Concept mergeable[alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, O, Comp, Proj1, Proj2>
constexpr ranges::merge_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, O>
ranges::merge(R1&& r1, R2&& r2, O result,
Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") I1, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I1> S1,
[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I2> S2,
[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") O, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<O> OutS, class Comp = ranges::less,
class Proj1 = identity, class Proj2 = identity>
requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7Concept mergeable[alg.req.mergeable]")<I1, I2, O, Comp, Proj1, Proj2>
ranges::merge_result<I1, I2, O>
ranges::merge(Ep&& exec, I1 first1, S1 last1, I2 first2, S2 last2, O result, OutS result_last,
Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6Other range refinements[range.refinements]") R1, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6Other range refinements[range.refinements]") R2,
[sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6Other range refinements[range.refinements]") OutR, class Comp = ranges::less,
class Proj1 = identity, class Proj2 = identity>
requires [mergeable](alg.req.mergeable#concept:mergeable "24.3.7.7Concept mergeable[alg.req.mergeable]")<iterator_t<R1>, iterator_t<R2>, iterator_t<OutR>, Comp, Proj1, Proj2>
ranges::merge_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>, borrowed_iterator_t<OutR>>
ranges::merge(Ep&& exec, R1&& r1, R2&& r2, OutR&& result_r,
Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {});
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10071)
Let:
- [(1.1)](#1.1)
N be:
* [(1.1.1)](#1.1.1)
(last1 - first1) + (last2 - first2) for the overloads with no parameter result_last or result_r;
* [(1.1.2)](#1.1.2)
min((last1 - first1) + (last2 - first2), result_last - result) for the overloads with parameters result_last or result_r;
- [(1.2)](#1.2)
comp be less{}, proj1 be identity{}, and proj2 be identity{},
for the overloads with no parameters by those names;
- [(1.3)](#1.3)
E(e1, e1) be bool(invoke(comp, invoke(proj2, e2), invoke(proj1, e1)));
- [(1.4)](#1.4)
K be the smallest integer in [0, last1 - first1)
such that for the element e1 in the position first1 + K there are at least N−K elements e2 in [first2, last2) for which E(e1, e1) holds,
and be equal to last1 - first1 if no such integer exists[.](#1.sentence-1)
[*Note [1](#note-1)*:
first1 + K points to the position past the last element to be copied[.](#1.4.sentence-2)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10103)
*Preconditions*: The ranges [first1, last1) and [first2, last2)
are sorted with respect to comp and proj1 or proj2,
respectively[.](#2.sentence-1)
The resulting range does not overlap with either of the original ranges[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10110)
*Effects*: Copies the first K elements of the range [first1, last1)
and the first N−K elements of the range [first2, last2)
into the range [result, result + N)[.](#3.sentence-1)
If an element a precedes b in an input range,a is copied into the output range before b[.](#3.sentence-2)
If e1 is an element of [first1, last1) ande2 of [first2, last2),e2 is copied into the output range before e1 if and only if E(e1, e1) is true[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10122)
*Returns*:
- [(4.1)](#4.1)
result + N for the overloads in namespace std[.](#4.1.sentence-1)
- [(4.2)](#4.2)
{first1 + K, first2 + N - K, result + N} for the overloads in namespace ranges[.](#4.2.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10133)
*Complexity*:
- [(5.1)](#5.1)
For the non-parallel algorithm overloads,
at most N−1 comparisons and applications of each projection[.](#5.1.sentence-1)
- [(5.2)](#5.2)
For the parallel algorithm overloads, O(N) comparisons and applications of each projection[.](#5.2.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10144)
*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8Requirements for stable algorithms"))[.](#6.sentence-1)
[🔗](#lib:inplace_merge)
`template<class BidirectionalIterator>
constexpr void inplace_merge(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last);
template<class ExecutionPolicy, class BidirectionalIterator>
void inplace_merge(ExecutionPolicy&& exec,
BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last);
template<class BidirectionalIterator, class Compare>
constexpr void inplace_merge(BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Compare comp);
template<class ExecutionPolicy, class BidirectionalIterator, class Compare>
void inplace_merge(ExecutionPolicy&& exec,
BidirectionalIterator first,
BidirectionalIterator middle,
BidirectionalIterator last, Compare comp);
template<[bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S, class Comp = ranges::less,
class Proj = identity>
requires [sortable](alg.req.sortable#concept:sortable "24.3.7.8Concept sortable[alg.req.sortable]")<I, Comp, Proj>
constexpr I ranges::inplace_merge(I first, I middle, S last, Comp comp = {}, Proj proj = {});
template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S,
class Comp = ranges::less, class Proj = identity>
requires [sortable](alg.req.sortable#concept:sortable "24.3.7.8Concept sortable[alg.req.sortable]")<I, Comp, Proj>
I ranges::inplace_merge(Ep&& exec, I first, I middle, S last, Comp comp = {}, Proj proj = {});
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10182)
Let comp be less{} and proj be identity{} for the overloads with no parameters by those names[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10187)
*Preconditions*: [first, middle) and [middle, last) are valid ranges
sorted with respect to comp and proj[.](#8.sentence-1)
For the overloads in namespace std,BidirectionalIterator meets
the [*Cpp17ValueSwappable*](swappable.requirements#:Cpp17ValueSwappable "16.4.4.3Swappable requirements[swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3Swappable requirements")) and
the type of *first meets
the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2Template argument requirements[utility.arg.requirements]") (Table [31](utility.arg.requirements#tab:cpp17.moveconstructible "Table 31: Cpp17MoveConstructible requirements")) and[*Cpp17MoveAssignable*](utility.arg.requirements#:Cpp17MoveAssignable "16.4.4.2Template argument requirements[utility.arg.requirements]") (Table [33](utility.arg.requirements#tab:cpp17.moveassignable "Table 33: Cpp17MoveAssignable requirements")) requirements[.](#8.sentence-2)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10198)
*Effects*: Merges two sorted consecutive ranges
[first, middle) and [middle, last),
putting the result of the merge into the range [first, last)[.](#9.sentence-1)
The resulting range is sorted with respect to comp and proj[.](#9.sentence-2)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10205)
*Returns*: last for the overload in namespace ranges[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10209)
*Complexity*: Let N=last - first:
- [(11.1)](#11.1)
For the non-parallel algorithm overloads, and
if enough additional memory is available, at most N−1 comparisons[.](#11.1.sentence-1)
- [(11.2)](#11.2)
Otherwise, O(NlogN) comparisons[.](#11.2.sentence-1)
In either case, twice as many projections as comparisons[.](#11.sentence-2)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10221)
*Remarks*: [Stable](algorithm.stable "16.4.6.8Requirements for stable algorithms[algorithm.stable]")[.](#12.sentence-1)
[🔗](#itemdecl:3)
`template<[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]") R, class Comp = ranges::less, class Proj = identity>
requires [sortable](alg.req.sortable#concept:sortable "24.3.7.8Concept sortable[alg.req.sortable]")<iterator_t<R>, Comp, Proj>
constexpr borrowed_iterator_t<R>
ranges::inplace_merge(R&& r, iterator_t<R> middle, Comp comp = {}, Proj proj = {});
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10234)
*Effects*: Equivalent to:return ranges::inplace_merge(ranges::begin(r), middle, ranges::end(r), comp, proj);
[🔗](#itemdecl:4)
`template<[execution-policy](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6Other range refinements[range.refinements]") R, class Comp = ranges::less,
class Proj = identity>
requires [sortable](alg.req.sortable#concept:sortable "24.3.7.8Concept sortable[alg.req.sortable]")<iterator_t<R>, Comp, Proj>
borrowed_iterator_t<R>
ranges::inplace_merge(Ep&& exec, R&& r, iterator_t<R> middle, Comp comp = {},
Proj proj = {});
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/algorithms.tex#L10252)
*Effects*: Equivalent to:return ranges::inplace_merge(std::forward<Ep>(exec), ranges::begin(r), middle,
ranges::end(r), comp, proj);