TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
non_recursive_merge_sort.cpp
Go to the documentation of this file.
1
7
#include <cstddef>
// for size_t
8
#include <iostream>
9
#include <utility>
// for std::move & std::remove_reference_t
10
11
namespace
sorting
{
12
template
<
class
Iterator>
13
void
merge
(Iterator, Iterator,
const
Iterator,
char
[]);
15
24
template
<
class
Iterator>
25
void
non_recursive_merge_sort
(
const
Iterator first,
const
Iterator last,
26
const
size_t
n) {
27
// create a buffer large enough to store all elements
28
// dynamically allocated to comply with cpplint
29
char
* buffer =
new
char
[n *
sizeof
(*first)];
30
// buffer size can be optimized to largest power of 2 less than n
31
// elements divide the container into equally-sized segments whose
32
// length start at 1 and keeps increasing by factors of 2
33
for
(
size_t
length(1); length < n; length <<= 1) {
34
// merge adjacent segments whose number is n / (length * 2)
35
Iterator left(first);
36
for
(
size_t
counter(n / (length << 1)); counter; --counter) {
37
Iterator right(left + length), end(right + length);
38
merge
(left, right, end, buffer);
39
left = end;
40
}
41
// if the number of remaining elements (n * 2 % length) is longer
42
// than a segment, merge the remaining elements
43
if
((n & ((length << 1) - 1)) > length)
44
merge
(left, left + length, last, buffer);
45
}
46
delete
[] buffer;
47
}
48
49
56
template
<
class
Iterator>
57
void
merge
(Iterator l, Iterator r,
const
Iterator e,
char
b[]) {
58
// create 2 pointers to point at the buffer
59
auto
p(
reinterpret_cast<
std::remove_reference_t<decltype(*l)
>
*>(b)), c(p);
60
// move the left part of the segment
61
for
(Iterator t(l); r != t; ++t) *p++ = std::move(*t);
62
// while neither the buffer nor the right part has been exhausted
63
// move the smallest element of the two back to the container
64
while
(e != r && c != p) *l++ = std::move(*r < *c ? *r++ : *c++);
65
// notice only one of the two following loops will be executed
66
// while the right part hasn't bee exhausted, move it back
67
while
(e != r) *l++ = std::move(*r++);
68
// while the buffer hasn't bee exhausted, move it back
69
while
(c != p) *l++ = std::move(*c++);
70
}
71
72
76
template
<
class
Iterator>
77
void
non_recursive_merge_sort
(
const
Iterator first,
const
size_t
n) {
78
non_recursive_merge_sort
(first, first + n, n);
79
}
80
81
85
template
<
class
Iterator>
86
void
non_recursive_merge_sort
(
const
Iterator first,
const
Iterator last) {
87
non_recursive_merge_sort
(first, last, last - first);
88
}
89
90
}
// namespace sorting
91
92
using
sorting::non_recursive_merge_sort
;
93
94
int
main
() {
95
int
size;
96
std::cout <<
"Enter the number of elements : "
;
97
std::cin >> size;
98
int
* arr =
new
int
[size];
99
for
(
int
i = 0; i < size; ++i) {
100
std::cout <<
"arr["
<< i <<
"] = "
;
101
std::cin >> arr[i];
102
}
103
non_recursive_merge_sort
(arr, size);
104
std::cout <<
"Sorted array\n"
;
105
for
(
int
i = 0; i < size; ++i)
106
std::cout <<
"arr["
<< i <<
"] = "
<< arr[i] <<
'\n'
;
107
delete
[] arr;
108
return
0;
109
}
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
sorting
for working with vectors
sorting::non_recursive_merge_sort
void non_recursive_merge_sort(const Iterator first, const Iterator last, const size_t n)
bottom-up merge sort which sorts elements in a non-decreasing order
Definition
non_recursive_merge_sort.cpp:25
sorting::merge
void merge(Iterator, Iterator, const Iterator, char[])
merges 2 sorted adjacent segments into a larger sorted segment
Definition
non_recursive_merge_sort.cpp:57
non_recursive_merge_sort
void non_recursive_merge_sort(const Iterator first, const Iterator last, const size_t n)
bottom-up merge sort which sorts elements in a non-decreasing order
Definition
non_recursive_merge_sort.cpp:25
sorting
non_recursive_merge_sort.cpp
Generated by
1.18.0