TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
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
11namespace sorting {
12template <class Iterator>
13void merge(Iterator, Iterator, const Iterator, char[]);
15
24template <class Iterator>
25void 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}
49
56template <class Iterator>
57void 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}
72
76template <class Iterator>
77void non_recursive_merge_sort(const Iterator first, const size_t n) {
78 non_recursive_merge_sort(first, first + n, n);
79}
81
85template <class Iterator>
86void 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
93
94int main(int argc, char** argv) {
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}
int main()
Main function.
for working with vectors
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
void merge(Iterator, Iterator, const Iterator, char[])
merges 2 sorted adjacent segments into a larger sorted segment