BAN: Implement basic radix sort for unsigned integers
This commit is contained in:
parent
c69efc040c
commit
d054e5b4b7
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/Math.h>
|
||||||
#include <BAN/Swap.h>
|
#include <BAN/Swap.h>
|
||||||
#include <BAN/Traits.h>
|
#include <BAN/Traits.h>
|
||||||
#include <BAN/Math.h>
|
#include <BAN/Vector.h>
|
||||||
|
|
||||||
namespace BAN::sort
|
namespace BAN::sort
|
||||||
{
|
{
|
||||||
|
@ -175,6 +176,61 @@ namespace BAN::sort
|
||||||
detail::intro_sort_impl(begin, end, 2 * Math::ilog2(len), comp);
|
detail::intro_sort_impl(begin, end, 2 * Math::ilog2(len), comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<unsigned_integral T>
|
||||||
|
consteval T lsb_index(T value)
|
||||||
|
{
|
||||||
|
for (T result = 0;; result++)
|
||||||
|
if (value & (1 << result))
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename It, size_t radix = 256>
|
||||||
|
requires is_unsigned_v<typename It::value_type> && (radix > 0 && (radix & (radix - 1)) == 0)
|
||||||
|
BAN::ErrorOr<void> radix_sort(It begin, It end)
|
||||||
|
{
|
||||||
|
using value_type = typename It::value_type;
|
||||||
|
|
||||||
|
const size_t len = distance(begin, end);
|
||||||
|
if (len <= 1)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
Vector<value_type> temp;
|
||||||
|
TRY(temp.resize(len));
|
||||||
|
|
||||||
|
Vector<size_t> counts;
|
||||||
|
TRY(counts.resize(radix));
|
||||||
|
|
||||||
|
constexpr size_t mask = radix - 1;
|
||||||
|
constexpr size_t shift = detail::lsb_index(radix);
|
||||||
|
|
||||||
|
for (size_t s = 0; s < sizeof(value_type) * 8; s += shift)
|
||||||
|
{
|
||||||
|
for (auto& cnt : counts)
|
||||||
|
cnt = 0;
|
||||||
|
for (It it = begin; it != end; ++it)
|
||||||
|
counts[(*it >> s) & mask]++;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < radix - 1; i++)
|
||||||
|
counts[i + 1] += counts[i];
|
||||||
|
|
||||||
|
for (It it = end; it != begin;)
|
||||||
|
{
|
||||||
|
--it;
|
||||||
|
temp[--counts[(*it >> s) & mask]] = *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < temp.size(); j++)
|
||||||
|
*next(begin, j) = temp[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
template<typename It, typename Comp = less<typename It::value_type>>
|
template<typename It, typename Comp = less<typename It::value_type>>
|
||||||
void sort(It begin, It end, Comp comp = {})
|
void sort(It begin, It end, Comp comp = {})
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue