diff --git a/DIRECTORY.md b/DIRECTORY.md index 693d8df32..c3dbf1fda 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -298,6 +298,7 @@ * [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) + * [Dnf Sort](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/sorting/dnf_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/dnf_sort.cpp b/sorting/dnf_sort.cpp new file mode 100644 index 000000000..0b13cffbe --- /dev/null +++ b/sorting/dnf_sort.cpp @@ -0,0 +1,109 @@ +/** + * @file + * @brief Implementation of the [DNF + * sort](https://www.geeksforgeeks.org/sort-an-array-of-0s-1s-and-2s/) implementation + * @details + * C++ program to sort an array with 0, 1 and 2 in a single pass(DNF sort). + * Since one traversal of the array is there hence it works in O(n) time + * complexity. + * @author [Sujal Gupta](https://github.com/heysujal) + */ + +#include /// for std::is_sorted +#include /// for assert +#include /// for std::swap and io operations +#include /// for std::vector + +/** + * @namespace sorting + * @breif Sorting algorithms + */ +namespace sorting { +/** + * @namespace dnf_sort + * @brief Functions for the [DNF + * sort](https://en.wikipedia.org/wiki/Dutch_national_flag_problem) implementation + */ +namespace dnf_sort { +/** + * @brief The main function implements DNF sort + * @tparam T type of array + * @param a array to be sorted, + * @param arr_size size of array + * @returns void + */ +template +std::vector dnfSort(const std::vector &in_arr) { + std::vector arr(in_arr); + uint64_t lo = 0; + uint64_t hi = arr.size() - 1; + uint64_t mid = 0; + + // Iterate till all the elements + // are sorted + while (mid <= hi) { + switch (arr[mid]) { + // If the element is 0 + case 0: + std::swap(arr[lo++], arr[mid++]); + break; + + // If the element is 1 . + case 1: + mid++; + break; + + // If the element is 2 + case 2: + std::swap(arr[mid], arr[hi--]); + break; + } + } + return arr; +} +} // namespace dnf_sort +} // namespace sorting + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + // 1st test + // [1, 0, 2, 1] return [0, 1, 1, 2] + std::vector array1 = {0, 1, 1, 2}; + std::cout << "Test 1... "; + std::vector arr1 = sorting::dnf_sort::dnfSort(array1); + assert(std::is_sorted(std::begin(arr1), std::end(arr1))); + std::cout << "passed" << std::endl; + // 2nd test + // [1, 0, 0, 1, 1, 0, 2, 1] return [0, 0, 0, 1, 1, 1, 1, 2] + std::vector array2 = {1, 0, 0, 1, 1, 0, 2, 1}; + std::cout << "Test 2... "; + std::vector arr2 = sorting::dnf_sort::dnfSort(array2); + assert(std::is_sorted(std::begin(arr2), std::end(arr2))); + std::cout << "passed" << std::endl; + // 3rd test + // [1, 1, 0, 0, 1, 2, 2, 0, 2, 1] return [0, 0, 0, 1, 1, 1, 1, 2, 2, 2] + std::vector array3 = {1, 1, 0, 0, 1, 2, 2, 0, 2, 1}; + std::cout << "Test 3... "; + std::vector arr3 = sorting::dnf_sort::dnfSort(array3); + assert(std::is_sorted(std::begin(arr3), std::end(arr3))); + std::cout << "passed" << std::endl; + // 4th test + // [2, 2, 2, 0, 0, 1, 1] return [0, 0, 1, 1, 2, 2, 2] + std::vector array4 = {2, 2, 2, 0, 0, 1, 1}; + std::cout << "Test 4... "; + std::vector arr4 = sorting::dnf_sort::dnfSort(array4); + assert(std::is_sorted(std::begin(arr4), std::end(arr4))); + std::cout << "passed" << std::endl; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + test(); // execute the test + return 0; +}