diff --git a/sorting/non_recursive_merge_sort.cpp b/sorting/non_recursive_merge_sort.cpp index 9d4e95f2f..c8c245b7d 100644 --- a/sorting/non_recursive_merge_sort.cpp +++ b/sorting/non_recursive_merge_sort.cpp @@ -8,83 +8,89 @@ #include #include // for std::move & std::remove_reference_t -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; +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); } - // 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; } - 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); -} + /// 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; diff --git a/sorting/quick_sort.cpp b/sorting/quick_sort.cpp index 1db6b014e..78268cf73 100644 --- a/sorting/quick_sort.cpp +++ b/sorting/quick_sort.cpp @@ -24,48 +24,53 @@ #include #include -/** - * This function takes last element as pivot, places - * the pivot element at its correct position in sorted - * array, and places all smaller (smaller than pivot) - * to left of pivot and all greater elements to right - * of pivot - * - */ +namespace sorting { + /** + * This function takes last element as pivot, places + * the pivot element at its correct position in sorted + * array, and places all smaller (smaller than pivot) + * to left of pivot and all greater elements to right + * of pivot + * + */ -int partition(int arr[], int low, int high) { - int pivot = arr[high]; // taking the last element as pivot - int i = (low - 1); // Index of smaller element + int partition(int arr[], int low, int high) { + int pivot = arr[high]; // taking the last element as pivot + int i = (low - 1); // Index of smaller element - for (int j = low; j < high; j++) { - // If current element is smaller than or - // equal to pivot - if (arr[j] <= pivot) { - i++; // increment index of smaller element - int temp = arr[i]; - arr[i] = arr[j]; - arr[j] = temp; + for (int j = low; j < high; j++) { + // If current element is smaller than or + // equal to pivot + if (arr[j] <= pivot) { + i++; // increment index of smaller element + int temp = arr[i]; + arr[i] = arr[j]; + 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); -} -/** - * 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); - } -} +} // namespace sorting + +using sorting::quickSort; // prints the array after sorting void show(int arr[], int size) {