Euphoria
radix_sort.h
Go to the documentation of this file.
1 #pragma once
2 
3 
4 
5 #include "base/cint.h"
6 
7 namespace eu::core
8 {
9  template <typename TInt>
10  struct BucketBase10
11  {
12  constexpr static int count = 10;
13 
14  static int
15  get_index(TInt i, int exp)
16  {
17  return (i / exp) % 10;
18  }
19 
20  static int
22  {
23  return 1;
24  }
25 
26  static bool
27  should_keep_looping(TInt max_value, int exp)
28  {
29  return max_value / exp > 0;
30  }
31 
32  static int
33  get_next_value(TInt, int exp)
34  {
35  return exp * 10;
36  }
37  };
38 
39  template <typename TInt>
40  struct BucketBase16
41  {
42  constexpr static int count = 16;
43 
44  static int
45  get_index(TInt i, int exp)
46  {
47  return (i >> (exp * 4)) & 0xF;
48  }
49 
50  static int
52  {
53  return 0;
54  }
55 
56  static bool
57  should_keep_looping(TInt max_value, int exp)
58  {
59  if(exp == 0) { return true; }
60  // -1 because we need to be sure we have passed the max value
61  // todo(Gustav): use some smart bit technique to set F up to exp
62  return max_value >= (1 << ((exp - 1) * 4));
63  }
64 
65  static int
66  get_next_value(TInt, int exp)
67  {
68  return exp + 1;
69  }
70  };
71 
72  template <typename T, typename TIdExtractor, typename TInt>
73  TInt
74  get_max(const std::vector<T>& arr)
75  {
76  TInt mx = TIdExtractor::get_id(arr[0]);
77  for(const auto& i: arr)
78  {
79  TInt val = TIdExtractor::get_id(i);
80  if(val > mx)
81  {
82  mx = val;
83  }
84  }
85  return mx;
86  }
87 
88  template <typename T, typename TIdExtractor, typename TBucket, typename TInt>
89  std::vector<T>
90  count_sort(const std::vector<T>& arr, int exp)
91  {
92  const int size = c_sizet_to_int(arr.size());
93 
94  int sum[TBucket::count] = {0,};
95 
96  for(auto arr_index = 0; arr_index < size; arr_index +=1)
97  {
98  sum[TBucket::get_index(TIdExtractor::get_id(arr[arr_index]), exp)]+=1;
99  }
100 
101  for(auto sum_index = 1; sum_index < TBucket::count; sum_index +=1)
102  {
103  sum[sum_index] += sum[sum_index - 1];
104  }
105 
106  // cant use reserve since that will not set the size, and we cant use resize
107  // or something else since that requires our object to be default
108  // constructable
109  // so we copy the array instead
110  // todo(Gustav): look into swapping the input array instead?
111  std::vector<T> ret = arr;
112 
113  for(auto arr_index = size - 1; arr_index >= 0; arr_index -=1)
114  {
115  auto sum_index = TBucket::get_index(TIdExtractor::get_id(arr[arr_index]), exp);
116  auto target = sum[sum_index] - 1;
117  ret[target] = arr[arr_index];
118  sum[sum_index] -= 1;
119  }
120 
121  return ret;
122  }
123 
124  // todo(Gustav): rename to do_inplace_radix_sort
125  template <typename T, typename TIdExtractor, typename TBucket, typename TInt>
126  void
127  do_inplace_radix_sort(std::vector<T>* arr)
128  {
129  const TInt max_value = get_max<T, TIdExtractor, TInt>(*arr);
130 
131  for(int exp = TBucket::get_start(); TBucket::should_keep_looping(max_value, exp);
132  exp = TBucket::get_next_value(max_value, exp))
133  {
134  *arr = count_sort<T, TIdExtractor, TBucket, TInt>(*arr, exp);
135  }
136  }
137 
138 }
139 
TInt get_max(const std::vector< T > &arr)
Definition: radix_sort.h:74
void do_inplace_radix_sort(std::vector< T > *arr)
Definition: radix_sort.h:127
std::vector< T > count_sort(const std::vector< T > &arr, int exp)
Definition: radix_sort.h:90
int c_sizet_to_int(size_t t)
Definition: cint.cc:11
constexpr static int count
Definition: radix_sort.h:12
static int get_index(TInt i, int exp)
Definition: radix_sort.h:15
static int get_next_value(TInt, int exp)
Definition: radix_sort.h:33
static int get_start()
Definition: radix_sort.h:21
static bool should_keep_looping(TInt max_value, int exp)
Definition: radix_sort.h:27
static int get_start()
Definition: radix_sort.h:51
static int get_index(TInt i, int exp)
Definition: radix_sort.h:45
static bool should_keep_looping(TInt max_value, int exp)
Definition: radix_sort.h:57
constexpr static int count
Definition: radix_sort.h:42
static int get_next_value(TInt, int exp)
Definition: radix_sort.h:66