added sorting algos to namespace sorting

This commit is contained in:
Krishna Vedala 2020-05-31 23:08:57 -04:00
parent c2c4681554
commit 5a2615c54e
2 changed files with 123 additions and 112 deletions

View File

@ -8,83 +8,89 @@
#include <iostream> #include <iostream>
#include <utility> // for std::move & std::remove_reference_t #include <utility> // for std::move & std::remove_reference_t
template <class Iterator> namespace sorting {
void merge(Iterator, Iterator, const Iterator, char[]); template <class Iterator>
/// bottom-up merge sort which sorts elements in a non-decreasing order 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 * sorts elements non-recursively by breaking them into small segments,
* segments by factors of 2 and repeating the same process. * merging adjacent segments into larger sorted segments, then increasing
* best-case = worst-case = O(n log(n)) * the sizes of segments by factors of 2 and repeating the same process.
* @param first points to the first element * best-case = worst-case = O(n log(n))
* @param last points to 1-step past the last element * @param first points to the first element
* @param n the number of elements * @param last points to 1-step past the last element
*/ * @param n the number of elements
template <class Iterator> */
void non_recursive_merge_sort(const Iterator first, const Iterator last, template <class Iterator>
const size_t n) { void non_recursive_merge_sort(const Iterator first, const Iterator last,
// create a buffer large enough to store all elements const size_t n) {
// dynamically allocated to comply with cpplint // create a buffer large enough to store all elements
char* buffer = new char[n * sizeof(*first)]; // dynamically allocated to comply with cpplint
// buffer size can be optimized to largest power of 2 less than n elements char* buffer = new char[n * sizeof(*first)];
// divide the container into equally-sized segments whose length start at 1 // buffer size can be optimized to largest power of 2 less than n
// and keeps increasing by factors of 2 // elements divide the container into equally-sized segments whose
for (size_t length(1); length < n; length <<= 1) { // length start at 1 and keeps increasing by factors of 2
// merge adjacent segments whose number is n / (length * 2) for (size_t length(1); length < n; length <<= 1) {
Iterator left(first); // merge adjacent segments whose number is n / (length * 2)
for (size_t counter(n / (length << 1)); counter; --counter) { Iterator left(first);
Iterator right(left + length), end(right + length); for (size_t counter(n / (length << 1)); counter; --counter) {
merge(left, right, end, buffer); Iterator right(left + length), end(right + length);
left = end; 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);
} }
// if the number of remaining elements (n * 2 % length) is longer delete[] buffer;
// 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
} /**
/// merges 2 sorted adjacent segments into a larger sorted segment * best-case = worst-case = O(n)
/** * @param l points to the left part
* best-case = worst-case = O(n) * @param r points to the right part, end of left part
* @param l points to the left part * @param e points to end of right part
* @param r points to the right part, end of left part * @param b points at the buffer
* @param e points to end of right part */
* @param b points at the buffer template <class Iterator>
*/ void merge(Iterator l, Iterator r, const Iterator e, char b[]) {
template <class Iterator> // create 2 pointers to point at the buffer
void merge(Iterator l, Iterator r, const Iterator e, char b[]) { auto p(reinterpret_cast<std::remove_reference_t<decltype(*l)>*>(b)),
// create 2 pointers to point at the buffer c(p);
auto p(reinterpret_cast<std::remove_reference_t<decltype(*l)>*>(b)), c(p); // move the left part of the segment
// move the left part of the segment for (Iterator t(l); r != t; ++t) *p++ = std::move(*t);
for (Iterator t(l); r != t; ++t) *p++ = std::move(*t); // while neither the buffer nor the right part has been exhausted
// while neither the buffer nor the right part has been exhausted // move the smallest element of the two back to the container
// move the smallest element of the two back to the container while (e != r && c != p) *l++ = std::move(*r < *c ? *r++ : *c++);
while (e != r && c != p) *l++ = std::move(*r < *c ? *r++ : *c++); // notice only one of the two following loops will be executed
// notice only one of the two following loops will be executed // while the right part hasn't bee exhausted, move it back
// while the right part hasn't bee exhausted, move it back while (e != r) *l++ = std::move(*r++);
while (e != r) *l++ = std::move(*r++); // while the buffer hasn't bee exhausted, move it back
// while the buffer hasn't bee exhausted, move it back while (c != p) *l++ = std::move(*c++);
while (c != p) *l++ = std::move(*c++); }
} /// bottom-up merge sort which sorts elements in a non-decreasing order
/// bottom-up merge sort which sorts elements in a non-decreasing order /**
/** * @param first points to the first element
* @param first points to the first element * @param n the number of elements
* @param n the number of elements */
*/ template <class Iterator>
template <class Iterator> void non_recursive_merge_sort(const Iterator first, const size_t n) {
void non_recursive_merge_sort(const Iterator first, const size_t n) { non_recursive_merge_sort(first, first + n, n);
non_recursive_merge_sort(first, first + n, n); }
} /// bottom-up merge sort which sorts elements in a non-decreasing order
/// bottom-up merge sort which sorts elements in a non-decreasing order /**
/** * @param first points to the first element
* @param first points to the first element * @param last points to 1-step past the last element
* @param last points to 1-step past the last element */
*/ template <class Iterator>
template <class Iterator> void non_recursive_merge_sort(const Iterator first, const Iterator last) {
void non_recursive_merge_sort(const Iterator first, const Iterator last) { non_recursive_merge_sort(first, last, last - first);
non_recursive_merge_sort(first, last, last - first); }
}
} // namespace sorting
using sorting::non_recursive_merge_sort;
int main(int argc, char** argv) { int main(int argc, char** argv) {
int size; int size;

View File

@ -24,48 +24,53 @@
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
/** namespace sorting {
* This function takes last element as pivot, places /**
* the pivot element at its correct position in sorted * This function takes last element as pivot, places
* array, and places all smaller (smaller than pivot) * the pivot element at its correct position in sorted
* to left of pivot and all greater elements to right * array, and places all smaller (smaller than pivot)
* of pivot * to left of pivot and all greater elements to right
* * of pivot
*/ *
*/
int partition(int arr[], int low, int high) { int partition(int arr[], int low, int high) {
int pivot = arr[high]; // taking the last element as pivot int pivot = arr[high]; // taking the last element as pivot
int i = (low - 1); // Index of smaller element int i = (low - 1); // Index of smaller element
for (int j = low; j < high; j++) { for (int j = low; j < high; j++) {
// If current element is smaller than or // If current element is smaller than or
// equal to pivot // equal to pivot
if (arr[j] <= pivot) { if (arr[j] <= pivot) {
i++; // increment index of smaller element i++; // increment index of smaller element
int temp = arr[i]; int temp = arr[i];
arr[i] = arr[j]; arr[i] = arr[j];
arr[j] = temp; arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return (i + 1);
}
/**
* The main function that implements QuickSort
* arr[] --> Array to be sorted,
* low --> Starting index,
* high --> Ending index
*/
void quickSort(int arr[], int low, int high) {
if (low < high) {
int p = partition(arr, low, high);
quickSort(arr, low, p - 1);
quickSort(arr, p + 1, high);
} }
} }
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return (i + 1);
}
/** } // namespace sorting
* The main function that implements QuickSort
* arr[] --> Array to be sorted, using sorting::quickSort;
* low --> Starting index,
* high --> Ending index
*/
void quickSort(int arr[], int low, int high) {
if (low < high) {
int p = partition(arr, low, high);
quickSort(arr, low, p - 1);
quickSort(arr, p + 1, high);
}
}
// prints the array after sorting // prints the array after sorting
void show(int arr[], int size) { void show(int arr[], int size) {