From b1079da17d34fed4327af58b222e8d04add4b635 Mon Sep 17 00:00:00 2001 From: Tsung-Han Ho Date: Wed, 21 Oct 2020 23:07:53 +0800 Subject: [PATCH] feat: add cycle sort algorithm (#1252) * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * feat: add cycle sort algorithm * updating DIRECTORY.md * Add namespace decription * fix: add assert and template * fix: add some comment * fix: update some suggested changes * fix: update some suggested changes Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> --- DIRECTORY.md | 1 + sorting/cycle_sort.cpp | 104 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 sorting/cycle_sort.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 31a9f4141..c857306da 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -240,6 +240,7 @@ * [Comb Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/comb_sort.cpp) * [Counting Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort.cpp) * [Counting Sort String](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/counting_sort_string.cpp) + * [Cycle Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/cycle_sort.cpp) * [Gnome Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/gnome_sort.cpp) * [Heap Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/heap_sort.cpp) * [Insertion Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/insertion_sort.cpp) diff --git a/sorting/cycle_sort.cpp b/sorting/cycle_sort.cpp new file mode 100644 index 000000000..2d14f399e --- /dev/null +++ b/sorting/cycle_sort.cpp @@ -0,0 +1,104 @@ +/** + * @file + * @brief Implementation of [Cycle sort](https://en.wikipedia.org/wiki/Cycle_sort) algorithm + * + * @details + * Cycle Sort is a sorting algorithm that works in \f$O(n^2)\f$ time in best cas and works in \f$O(n^2)\f$ in worst case. + * If a element is already at its correct position, do nothing. + * If a element is not at its correct position, we then need to move it to its correct position by computing the correct positions.Therefore, we should make sure the duplicate elements. + * + * @author [TsungHan Ho](https://github.com/dalaoqi) + */ + +#include /// for std::is_sorted, std::swap +#include /// for assert +#include /// for io operations +#include /// for std::vector + +/** + * @namespace sorting + * @brief Sorting algorithms + */ +namespace sorting { +/** + * @namespace cycle_sort + * @brief Functions for [Cycle sort](https://en.wikipedia.org/wiki/Cycle_sort) algorithm + */ +namespace cycle_sort { +/** + * @brief The main function implements cycleSort + * @tparam T type of array + * @param in_arr array to be sorted + * @returns void + */ +template +std::vector cycleSort(const std::vector &in_arr) { + std::vector arr(in_arr); + for (size_t cycle_start = 0; cycle_start <= arr.size() - 1; cycle_start++) { + // initialize item + T item = arr[cycle_start]; + + // Count the number of elements smaller than item, this number is the correct index of item. + int pos = cycle_start; + for (size_t i = cycle_start + 1; i < arr.size(); i++) { + if (arr[i] < item) { + pos++; + } + } + + // item is already in correct position + if (pos == cycle_start) { + continue; + } + + // duplicate elements + while (item == arr[pos]) pos += 1; + std::swap(item, arr[pos]); + + // Rest of the elements + while (pos != cycle_start) { + pos = cycle_start; + // Find position where we put the element + for (size_t i = cycle_start + 1; i < arr.size(); i++) { + if (arr[i] < item) { + pos += 1; + } + } + // duplicate elements + while (item == arr[pos]) pos += 1; + std::swap(item, arr[pos]); + } + } + return arr; +} +} // namespace cycle_sort +} // namespace sorting + +/** + * @brief Test implementations + * @returns void + */ +static void test() { + // [506, 48, 123, 79, 0, 362, 951, 500, 0] return [0, 0, 48, 79, 123, 362, 500, 506, 951] + std::vector array1 = {506, 48, 123, 79, 0, 362, 951, 500, 0}; + std::cout << "Test 1... "; + std::vector arr1 = sorting::cycle_sort::cycleSort(array1); + assert(std::is_sorted(std::begin(arr1), std::end(arr1))); + std::cout << "passed" << std::endl; + + // [4.3, -6.5, -7.4, 0, 2.7, 1.8] return [-7.4, -6.5, 0, 1.8, 2.7, 4.3] + std::vector array2 = {4.3, -6.5, -7.4, 0, 2.7, 1.8}; + std::cout << "Test 2... "; + std::vector arr2 = sorting::cycle_sort::cycleSort(array2); + assert(std::is_sorted(std::begin(arr2), std::end(arr2))); + std::cout << "passed" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the test + return 0; +}