From 255d7efe9fc26e7bfe5bd28d07119223cea6d1e3 Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Sat, 29 May 2021 14:23:23 -0400 Subject: [PATCH] Add example for radix sort --- cpp/algorithms/sorting/CMakeLists.txt | 1 + cpp/algorithms/sorting/radix/CMakeLists.txt | 19 ++++++ cpp/algorithms/sorting/radix/lib-counting.cpp | 65 +++++++++++++++++++ cpp/algorithms/sorting/radix/lib-counting.hpp | 19 ++++++ cpp/algorithms/sorting/radix/lib-radix.cpp | 29 +++++++++ cpp/algorithms/sorting/radix/lib-radix.hpp | 18 +++++ cpp/algorithms/sorting/radix/radix-sort.cpp | 45 +++++++++++++ 7 files changed, 196 insertions(+) create mode 100644 cpp/algorithms/sorting/radix/CMakeLists.txt create mode 100644 cpp/algorithms/sorting/radix/lib-counting.cpp create mode 100644 cpp/algorithms/sorting/radix/lib-counting.hpp create mode 100644 cpp/algorithms/sorting/radix/lib-radix.cpp create mode 100644 cpp/algorithms/sorting/radix/lib-radix.hpp create mode 100644 cpp/algorithms/sorting/radix/radix-sort.cpp diff --git a/cpp/algorithms/sorting/CMakeLists.txt b/cpp/algorithms/sorting/CMakeLists.txt index 3b0f31d..abd1123 100644 --- a/cpp/algorithms/sorting/CMakeLists.txt +++ b/cpp/algorithms/sorting/CMakeLists.txt @@ -23,3 +23,4 @@ add_subdirectory(heap) add_subdirectory(quick) add_subdirectory(count) add_subdirectory(bucket) +add_subdirectory(radix) diff --git a/cpp/algorithms/sorting/radix/CMakeLists.txt b/cpp/algorithms/sorting/radix/CMakeLists.txt new file mode 100644 index 0000000..ba4612f --- /dev/null +++ b/cpp/algorithms/sorting/radix/CMakeLists.txt @@ -0,0 +1,19 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: A basic CMakeLists configuration to practice radix sort ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### + +cmake_minimum_required(VERSION 3.16) +project(RadixSort LANGUAGES CXX) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +add_executable(radix-sort "radix-sort.cpp") + +add_library(lib-counting "lib-counting.cpp") +add_library(lib-radix "lib-radix.cpp") + +target_link_libraries(radix-sort lib-radix lib-counting) diff --git a/cpp/algorithms/sorting/radix/lib-counting.cpp b/cpp/algorithms/sorting/radix/lib-counting.cpp new file mode 100644 index 0000000..53cb154 --- /dev/null +++ b/cpp/algorithms/sorting/radix/lib-counting.cpp @@ -0,0 +1,65 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: An example implementation of counting sort using a custom library ## +## + In support of a radix sort implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### +*/ + +#include "lib-counting.hpp" + +#include +#include +#include + + +void CountingSort(std::vector &array, int placeValue) +{ + std::vector sortedArray(array.size(), 0); + + // Find the maximum value within the array to sort + int32_t maxValue = INT32_MIN; + for (const auto &val : array) maxValue = (val > maxValue) ? val : maxValue; + + // Create an array with element for all *placeValues* within range of the set + // + Not the size of the array to sort, but instead a element of + // + tempArray[digit] = 0; Considering only the digit at placeValue of array[n] + // Using this vector, we have a place to count all possible digits at placeValue + std::vector tempArray(10, 0); + + // Count the occurrences of each digit at this placeValue within the array + // + Store the end result as tempArray[digit] = count; + // + Where digit is found at the decimal placeValue of each value within array + for (const auto &val : array) { + // Get the digit at the decimal placeValue of arrayValue + auto index = static_cast((val / placeValue) % tempArray.size()); + // Running total of each value with the same digit at decimal placeValue + tempArray[index] = tempArray[index] + 1; + } + + // Count the values less than or equal to each element of tempArray + // + Since each element stores its own count, just add the count at index i-1 + for (int i = 1; i < tempArray.size(); i++) { + tempArray[i] = tempArray[i] + tempArray[i - 1]; + } + + for (ssize_t arrayIndex = array.size() - 1; arrayIndex >= 0; arrayIndex--) { + // Get the value to consider from the unsorted array + const int &arrayValue = array[arrayIndex]; + + // Get the digit at the decimal placeValue of arrayValue + // + Use this index to update count of values as we use them + const auto tempIndex = + static_cast((arrayValue / placeValue) % tempArray.size()); + + // Store valueCount as a reference so we can update it + int &valueCount = tempArray[tempIndex]; + // Offset valueCount by 1 to allow for zero index of sortedArray + sortedArray[valueCount - 1] = arrayValue; + valueCount = valueCount - 1; + } + + array = sortedArray; +} diff --git a/cpp/algorithms/sorting/radix/lib-counting.hpp b/cpp/algorithms/sorting/radix/lib-counting.hpp new file mode 100644 index 0000000..2fb09b8 --- /dev/null +++ b/cpp/algorithms/sorting/radix/lib-counting.hpp @@ -0,0 +1,19 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: An example implementation of counting sort using a custom library ## +## + In support of a radix sort implementation ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### +*/ + +#ifndef RADIX_LIB_COUNT_HPP +#define RADIX_LIB_COUNT_HPP + +#include + + +void CountingSort(std::vector &array, int placeValue); + +#endif // RADIX_LIB_COUNT_HPP diff --git a/cpp/algorithms/sorting/radix/lib-radix.cpp b/cpp/algorithms/sorting/radix/lib-radix.cpp new file mode 100644 index 0000000..0bee905 --- /dev/null +++ b/cpp/algorithms/sorting/radix/lib-radix.cpp @@ -0,0 +1,29 @@ + +#include "lib-radix.hpp" +#include "lib-counting.hpp" + +#include +#include + + +void RadixSort(std::vector &array) +{ + int maxValue = *std::max_element(array.begin(), array.end()); + // Get the total number of digits in the maximum value within the set + // + 100 has 3 digits; 10 has 2 digits; etc.. + int digits = 0; + for (int tempMax = maxValue; tempMax > 0; tempMax /= 10) digits++; + + // For each placeValue of the maximum value within the set + for (int placeValue = 1; maxValue / placeValue > 0; placeValue *= 10) { + // Perform counting sort on all values, only considering the placeValue digit + // Result of sorting the first placeValue: + // + 12, 10, 15, 5, 3, 101, 109, 115 -> 10, 101, 12, 3, 115, 15, 5, 109 + // Result of sorting the second placeValue: + // + 10, 101, 12, 3, 115, 15, 5, 109 -> 3, 5, 101, 109, 10, 12, 115, 15 + // Result of sorting the third placeValue: + // + 3, 5, 101, 109, 10, 12, 115, 15 -> 3, 5, 10, 12, 15, 101, 109, 115 + CountingSort(array, placeValue); + } + +} diff --git a/cpp/algorithms/sorting/radix/lib-radix.hpp b/cpp/algorithms/sorting/radix/lib-radix.hpp new file mode 100644 index 0000000..a83fe60 --- /dev/null +++ b/cpp/algorithms/sorting/radix/lib-radix.hpp @@ -0,0 +1,18 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: An example implementation of radix sort using a custom library ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### +*/ + +#ifndef LIB_RADIX_HPP +#define LIB_RADIX_HPP + +#include + + +void RadixSort(std::vector &array); + +#endif // LIB_RADIX_HPP diff --git a/cpp/algorithms/sorting/radix/radix-sort.cpp b/cpp/algorithms/sorting/radix/radix-sort.cpp new file mode 100644 index 0000000..45cbb15 --- /dev/null +++ b/cpp/algorithms/sorting/radix/radix-sort.cpp @@ -0,0 +1,45 @@ +/*############################################################################# +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: An example implementation of radix sort using a custom library ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################### +*/ + +#include "lib-counting.hpp" +#include "lib-radix.hpp" + +#include +#include +#include +#include + +// More values increase chance that the set provides colliding placeValue digits +#define ARRAY_LENGTH 20 + + +int main(const int argc, const char * argv[]) +{ + srand(time(nullptr)); + std::vector array(ARRAY_LENGTH); + // For this example, we limit the maximum value to 150 + // + This helps to provide values with 1, 2, or 3 total placeValue digits + // + Possible to get 0-9, 10-99, and 100-149 + std::generate(array.begin(), array.end(), [](){ return rand() % 150;}); + + auto print = [](std::vector array) { + for (const auto &i : array) { + std::cout << i << ", "; + } + std::cout << std::endl; + }; + + std::cout << "Unsorted array: \n"; + print(array); + + RadixSort(array); + + std::cout << "Sorted array: \n"; + print(array); +}