From 69105f882df5a5bb95bf63a16f6b0c14eb22a948 Mon Sep 17 00:00:00 2001 From: = <=> Date: Sat, 30 Oct 2021 00:05:33 +0530 Subject: [PATCH] added non recursive merge sort --- .../{linearsort.c++ => linearsort.cpp} | 54 ++++----- .../non_recursive_merge_sort.cpp | 106 ++++++++++++++++++ 2 files changed, 133 insertions(+), 27 deletions(-) rename Sorting Algorithms/{linearsort.c++ => linearsort.cpp} (93%) create mode 100644 Sorting Algorithms/non_recursive_merge_sort.cpp diff --git a/Sorting Algorithms/linearsort.c++ b/Sorting Algorithms/linearsort.cpp similarity index 93% rename from Sorting Algorithms/linearsort.c++ rename to Sorting Algorithms/linearsort.cpp index cf95cc6c..6fcc5857 100644 --- a/Sorting Algorithms/linearsort.c++ +++ b/Sorting Algorithms/linearsort.cpp @@ -1,28 +1,28 @@ -#include -#include -void main() -{ -clrscr(); -int a[50],i,n,j,temp; -cout<<"Enter number of elements: "; -cin>>n; -cout<<"Enter array elements: "; -for(i=0;i>a[i]; -for(i=0;ia[j]) - { - temp=a[i]; - a[i]=a[j]; - a[j]=temp; - } - } -} -cout<<"Sorted array is: "; -for(i=0;i +#include +void main() +{ +clrscr(); +int a[50],i,n,j,temp; +cout<<"Enter number of elements: "; +cin>>n; +cout<<"Enter array elements: "; +for(i=0;i>a[i]; +for(i=0;ia[j]) + { + temp=a[i]; + a[i]=a[j]; + a[j]=temp; + } + } +} +cout<<"Sorted array is: "; +for(i=0;i // for size_t +#include +#include // for std::move & std::remove_reference_t + +namespace sorting { +template +void merge(Iterator, Iterator, const Iterator, char[]); +/// bottom-up merge sort which sorts elements in a non-decreasing order +/** + * sorts elements non-recursively by breaking them into small segments, + * merging adjacent segments into larger sorted segments, then increasing + * the sizes of segments by factors of 2 and repeating the same process. + * best-case = worst-case = O(n log(n)) + * @param first points to the first element + * @param last points to 1-step past the last element + * @param n the number of elements + */ +template +void non_recursive_merge_sort(const Iterator first, const Iterator last, + const size_t n) { + // create a buffer large enough to store all elements + // dynamically allocated to comply with cpplint + char* buffer = new char[n * sizeof(*first)]; + // buffer size can be optimized to largest power of 2 less than n + // elements divide the container into equally-sized segments whose + // length start at 1 and keeps increasing by factors of 2 + for (size_t length(1); length < n; length <<= 1) { + // merge adjacent segments whose number is n / (length * 2) + Iterator left(first); + for (size_t counter(n / (length << 1)); counter; --counter) { + Iterator right(left + length), end(right + length); + merge(left, right, end, buffer); + left = end; + } + // if the number of remaining elements (n * 2 % length) is longer + // than a segment, merge the remaining elements + if ((n & ((length << 1) - 1)) > length) + merge(left, left + length, last, buffer); + } + delete[] buffer; +} +/// merges 2 sorted adjacent segments into a larger sorted segment +/** + * best-case = worst-case = O(n) + * @param l points to the left part + * @param r points to the right part, end of left part + * @param e points to end of right part + * @param b points at the buffer + */ +template +void merge(Iterator l, Iterator r, const Iterator e, char b[]) { + // create 2 pointers to point at the buffer + auto p(reinterpret_cast*>(b)), c(p); + // move the left part of the segment + for (Iterator t(l); r != t; ++t) *p++ = std::move(*t); + // while neither the buffer nor the right part has been exhausted + // move the smallest element of the two back to the container + while (e != r && c != p) *l++ = std::move(*r < *c ? *r++ : *c++); + // notice only one of the two following loops will be executed + // while the right part hasn't bee exhausted, move it back + while (e != r) *l++ = std::move(*r++); + // while the buffer hasn't bee exhausted, move it back + while (c != p) *l++ = std::move(*c++); +} +/// bottom-up merge sort which sorts elements in a non-decreasing order +/** + * @param first points to the first element + * @param n the number of elements + */ +template +void non_recursive_merge_sort(const Iterator first, const size_t n) { + non_recursive_merge_sort(first, first + n, n); +} +/// bottom-up merge sort which sorts elements in a non-decreasing order +/** + * @param first points to the first element + * @param last points to 1-step past the last element + */ +template +void non_recursive_merge_sort(const Iterator first, const Iterator last) { + non_recursive_merge_sort(first, last, last - first); +} + +} // namespace sorting + +using sorting::non_recursive_merge_sort; + +int main(int argc, char** argv) { + int size; + std::cout << "Enter the number of elements : "; + std::cin >> size; + int* arr = new int[size]; + for (int i = 0; i < size; ++i) { + std::cout << "arr[" << i << "] = "; + std::cin >> arr[i]; + } + non_recursive_merge_sort(arr, size); + std::cout << "Sorted array\n"; + for (int i = 0; i < size; ++i) + std::cout << "arr[" << i << "] = " << arr[i] << '\n'; + delete[] arr; + return 0; +}