281 lines
15 KiB
Markdown
281 lines
15 KiB
Markdown
[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.9 Concept input_iterator [iterator.concept.input]") I1, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I1> S1, [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]") I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I2> S2,
|
||
[weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept 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.7 Concept 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.6 Other range refinements [range.refinements]") R1, [input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R2, [weakly_incrementable](iterator.concept.winc#concept:weakly_incrementable "24.3.4.4 Concept 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.7 Concept 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.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") I1, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I1> S1,
|
||
[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I2> S2,
|
||
[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") O, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept 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.7 Concept 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.1 Preamble [algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R1, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R2,
|
||
[sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other 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.7 Concept 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.8 Requirements 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.12 Concept bidirectional_iterator [iterator.concept.bidir]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S, class Comp = ranges::less,
|
||
class Proj = identity>
|
||
requires [sortable](alg.req.sortable#concept:sortable "24.3.7.8 Concept 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.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept 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.8 Concept 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.3 Swappable requirements [swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements")) and
|
||
the type of *first meets
|
||
the [*Cpp17MoveConstructible*](utility.arg.requirements#:Cpp17MoveConstructible "16.4.4.2 Template 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.2 Template 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.8 Requirements for stable algorithms [algorithm.stable]")[.](#12.sentence-1)
|
||
|
||
[ð](#itemdecl:3)
|
||
|
||
`template<[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]") R, class Comp = ranges::less, class Proj = identity>
|
||
requires [sortable](alg.req.sortable#concept:sortable "24.3.7.8 Concept 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.1 Preamble [algorithms.parallel.defns]") Ep, [sized-random-access-range](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") R, class Comp = ranges::less,
|
||
class Proj = identity>
|
||
requires [sortable](alg.req.sortable#concept:sortable "24.3.7.8 Concept 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);
|