Skip to content

Commit 8696129

Browse files
authored
Merge pull request deutranium#191 from rcchcz/radix-new-version
Radix new version
2 parents 889e0a1 + 6647c24 commit 8696129

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include <sstream>
2+
#include <iterator>
3+
#include <functional>
4+
#include <vector>
5+
#include <array>
6+
#include <algorithm>
7+
#include <cmath>
8+
#include <string>
9+
#include <bits/stdc++.h>
10+
#include <type_traits>
11+
#include <utility>
12+
#include <iomanip>
13+
#include <iostream>
14+
/*!
15+
* This function implements the Radix Sorting Algorithm based on the **less significant digit** (LSD).
16+
*
17+
* @note This is a non-comparison sort algorithm. This version works for any kind of integers.
18+
*
19+
* @param v Vector to be sorted.
20+
*/
21+
void radix(std::vector<int> &v) {
22+
// the number of digits of max element indicates how many times the main loop will be executed
23+
int maxDig = std::to_string(*std::max_element(v.begin(), v.end())).size();
24+
25+
// one bucket for each digit from 0 to 9
26+
std::array<std::vector<int>, 10> buckets;
27+
28+
// main loop; maxDig times
29+
for(int i = 0; i < maxDig; i++) {
30+
// inter loop; insert each element into its respective bucket depending on which digit position is being analyzed
31+
std::for_each(v.begin(), v.end(), [&buckets, i](int value){ buckets[(int)(value/std::pow(10, i))%10].push_back(value); });
32+
33+
// ==============================================================
34+
// What the for_each above does is:
35+
// --------------------------------------------------------------
36+
// Assuming value = 123 and that the largest number in the collection has 4 digits.
37+
// 1st pass: 123/1 = 123; 123 % 10 = 3. buckets[3].push_back(123).
38+
// 2nd pass: 123/10 = 12; 12 % 10 = 2. buckets[2].push_back(123).
39+
// 3rd pass: 123/100 = 1; 1 % 10 = 1. buckets[1].push_back(123).
40+
// 4th pass: 123/1000 = 0; 0 % 10 = 0. buckets[0].push_back(123).
41+
// ==============================================================
42+
43+
// copy from buckets to the original range
44+
auto destination = v.begin();
45+
for(auto &b : buckets) {
46+
destination = std::copy(b.begin(), b.end(), destination);
47+
b.clear();
48+
}
49+
}
50+
}
51+
52+
/*!
53+
* Simple print function.
54+
*/
55+
void printV(std::vector<int> v) {
56+
for(int i = 0; i < v.size(); i++) std::cout << v[i] << " ";
57+
std::cout << std::endl;
58+
}
59+
60+
/*!
61+
* This function separates the main vector into two: one containing negative integers and one containing non-negative integers.
62+
*
63+
* @param v Vector with non-negative integers.
64+
* @param negV Vector with negative integers.
65+
*/
66+
void splitV(std::vector<int> &v, std::vector<int> &negV) {
67+
for(int i = 0; i < v.size(); i++) {
68+
if(v[i] < 0) {
69+
negV.push_back(v[i]);
70+
v.erase(v.begin() + i);
71+
}
72+
}
73+
}
74+
75+
/*!
76+
* This function converts positive to negative and negative to positive.
77+
*
78+
* @param v Vector whose elements will be changed.
79+
*/
80+
void negPos(std::vector<int> &v) {
81+
for(auto &a : v) {
82+
a *= -1;
83+
}
84+
}
85+
86+
/*!
87+
* This function joinVs two vectors.
88+
*
89+
* @param v Vector with non-negative integers.
90+
* @param negV Vector with negative integers.
91+
*/
92+
void joinV(std::vector<int> &v, std::vector<int> &negV) {
93+
// reverses because the original values are negative
94+
std::reverse(negV.begin(), negV.end());
95+
for(auto &a : negV) v.insert(v.begin(), a);
96+
}
97+
98+
99+
int main() {
100+
std::vector<int> v = {23, -10, 20, -11, 12, -6, 7};
101+
std::vector<int> negV;
102+
103+
splitV(v, negV);
104+
105+
negPos(negV);
106+
107+
radix(v);
108+
radix(negV);
109+
110+
negPos(negV);
111+
112+
joinV(v, negV);
113+
114+
std::cout << "Sorted: ";
115+
printV(v);
116+
117+
return 0;
118+
}

0 commit comments

Comments
 (0)