mirror of
https://hub.njuu.cf/TheAlgorithms/C-Plus-Plus.git
synced 2023-10-11 13:05:55 +08:00
added sorting algos to namespace sorting
This commit is contained in:
parent
c2c4681554
commit
5a2615c54e
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user