/** * @file * @brief Algorithm of [Radix sort](https://en.wikipedia.org/wiki/Radix_sort) * @author [Suyash Jaiswal](https://github.com/Suyashjaiswal) * @details * Sort the vector of unsigned integers using radix sort i.e. sorting digit by digit * using [Counting Sort](https://en.wikipedia.org/wiki/Counting_sort) as subroutine. * Running time of radix sort is O(d*(n+b)) where b is the base for representing * numbers and d in the max digits in input integers and n is number of unsigned integers. * consider example for n = 5, aray elements = 432,234,143,332,123 * sorting digit by digit * sorting according to * 1) 1st digit place * => 432, 332, 143, 123, 234 * * 2) 2nd digit place * => 123, 432, 332, 234, 143 * * 3) 3rd digit place * => 123, 143, 234, 332, 432 * * using count sort at each step, which is stable. * stable => already sorted according to previous digits. */ /// header files #include /// for io operations #include /// for std::vector #include /// for collection of functions #include /// for a macro called assert which can be used to verify assumptions /** * @namespace sorting * @brief Sorting algorithms */ namespace sorting { /** * @namespace radix_sort * @brief Functions for [Radix sort](https://en.wikipedia.org/wiki/Radix_sort) * algorithm */ namespace radix_sort { /** * @brief Function to sort vector according to current digit using stable * sorting. * @param cur_digit - sort according to the cur_digit * @param ar - vector to be sorted * @returns std::vector sorted till ith digit */ std::vector step_ith(uint16_t cur_digit, const std::vector& ar) { // sorting according to current digit. int n = ar.size(); std::vector position(10, 0); for (int i = 0; i < n; ++i) { position[(ar[i] / cur_digit) % 10]++; // counting frequency of 0-9 at cur_digit. } int cur = 0; for (int i = 0; i < 10; ++i) { int a = position[i]; position[i] = cur; // assingning starting position of 0-9. cur += a; } std::vector temp(n); for (int i = 0; i < n; ++i) { temp[position[(ar[i] / cur_digit) % 10]] = ar[i]; // storing ar[i] in ar[i]'s cur_digit expected position of // this step. position[(ar[i] / cur_digit) % 10]++; // incrementing ar[i]'s cur_digit position by 1, as // current place used by ar[i]. } return temp; } /** * @brief Function to sort vector digit by digit. * @param ar - vector to be sorted * @returns sorted vector */ std::vector radix(const std::vector& ar) { uint64_t max_ele = *max_element(ar.begin(), ar.end()); // returns the max element. std::vector temp = ar; for (int i = 1; max_ele / i > 0; i *= 10) { // loop breaks when i > max_ele because no further digits // left to makes changes in aray. temp = step_ith(i,temp); } for (uint64_t i : temp) { std::cout << i << " "; } std::cout << "\n"; return temp; } } // namespace radix_sort } // namespace sorting /** * @brief Function to test the above algorithm * @returns none */ static void tests() { /// Test 1 std::vector ar1 = {432, 234, 143, 332, 123}; ar1 = sorting::radix_sort::radix(ar1); assert(std::is_sorted(ar1.begin(), ar1.end())); /// Test 2 std::vector ar2 = {213, 3214, 123, 111, 112, 142, 133, 132, 32, 12, 113}; ar2 = sorting::radix_sort::radix(ar2); assert(std::is_sorted(ar2.begin(), ar2.end())); } /** * @brief Main function * @returns 0 on exit */ int main() { tests(); // execute the tests return 0; }