forked from ProAlgos/ProAlgos-Cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
counting_sort.cpp
97 lines (75 loc) · 2.69 KB
/
counting_sort.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
Counting sort (stable)
----------------------
An integer sorting algorithm that operates by counting the number of objects
that have each distinct key value, and using arithmetic on those counts to
determine the positions of each key value in the output sequence.
Time complexity
---------------
O(N + R), where N is the number of elements and R is the range of input.
Space complexity
----------------
O(N), where N is the number of elements.
*/
#include <iostream>
#include <vector>
#include "sorting/utils.hpp"
using namespace std;
void counting_sort(vector<int>& values, const int order = 1, const bool to_show_state = false) {
int min_value = values[0];
int max_value = values[0];
// find minimum and maximum values in input vector
for (int value: values) {
if (value < min_value)
min_value = value;
else if (value > max_value)
max_value = value;
}
// calculate unique values in input vector
const int unique_values = max_value - min_value + 1;
// calculate frequencies of each unique value in input vector
// freq[0] is number of min_value occurencies and so on
vector<int> freq(unique_values, 0);
for (int value: values)
++freq[value - min_value];
// start and end indices, for calculating cumulative frequency
int start = 1;
int end = freq.size();
// if order is reversed, the indices are reversed too
if (order == -1) { // 'order' is -1 for descending, 1 for ascending
start = freq.size() - 2;
end = -1;
}
// calculate cumulative frequency:
// freq[i] will now be the number of elements in the sorted array that are
// less than or equal to value[i]
for (int i = start; i != end; i += order)
freq[i] += freq[i - order];
// place values in sorted order by iterating input vector in reversed order,
// to maintain sorting stability
vector<int> sorted(values.size());
int value;
for (auto iter = values.rbegin(); iter != values.rend(); ++iter) {
value = *iter;
sorted[freq[value - min_value] - 1] = value;
--freq[value - min_value];
if (to_show_state)
display_state(sorted);
}
values.assign(sorted.begin(), sorted.end());
}
int main() {
size_t size;
get_input_size(size);
vector<int> values(size);
get_input_values(values, size);
int order;
string order_text;
get_order(order, order_text);
bool to_show_state;
get_whether_to_show_state(to_show_state);
counting_sort(values, order, to_show_state);
cout << "\nThe values in " << order_text << " order are:\n";
display_state(values);
return 0;
}