Guest User

Untitled

a guest
Oct 24th, 2025
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.68 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <chrono>
  3. #include <algorithm>
  4. #include <cassert>
  5. #include <iostream>
  6. #include <limits>
  7. #include <vector>
  8.  
  9. using namespace std;
  10. using namespace std::chrono;
  11.  
  12. void sortit(vector<int> &arr, int base = 1 << 15) {
  13.     int n = arr.size();
  14.     int modder = base - 1;
  15.     vector<vector<int>> grps(base);
  16.     vector<int> cnts(base + 1), live(base);
  17.     for (int i = 0; i < n; i++) {
  18.         int z = arr[i] >> 15;
  19.         grps[arr[i] & modder].push_back(z);//adding each element in respective group
  20.         cnts[z + 1]++;//increasing count
  21.     }
  22.     for (int i = 1; i < base; i++) cnts[i] += cnts[i - 1]; //making prefix array
  23.  
  24.     for (int i = 0; i < base; i++) {
  25.         for (int &x : grps[i]) arr[cnts[x] + live[x]++] = (x << 15) + i;
  26.     }
  27. }
  28.  
  29.  
  30. struct identity_extract {
  31.     template<typename T>
  32.     T operator()(const T &x) const {
  33.         return x;
  34.     }
  35. };
  36.  
  37. // A stable sort that sorts in passes of `bits_per_pass` bits at a time.
  38. template<typename T, typename T_extract_key = identity_extract>
  39. void radix_sort(vector<T> &data, const T_extract_key &extract_key = identity_extract(), int bits_per_pass = 10) {
  40.     if (data.empty() || int64_t(data.size()) * (64 - __builtin_clzll(data.size())) < 2 * (1 << bits_per_pass)) {
  41.         stable_sort(data.begin(), data.end(), [&](const T &a, const T &b) -> bool {
  42.             return extract_key(a) < extract_key(b);
  43.         });
  44.         return;
  45.     }
  46.  
  47.     using T_key = decltype(extract_key(data.front()));
  48.     T_key minimum = numeric_limits<T_key>::max(), maximum = numeric_limits<T_key>::lowest();
  49.  
  50.     for (T &x : data) {
  51.         T_key key = extract_key(x);
  52.         minimum = min(minimum, key);
  53.         maximum = max(maximum, key);
  54.     }
  55.  
  56.     int max_bits = minimum == maximum ? 0 : 64 - __builtin_clzll(maximum - minimum);
  57.     int passes = max((max_bits + bits_per_pass / 2) / bits_per_pass, 1);
  58.  
  59.     if (64 - __builtin_clzll(data.size()) <= 1.5 * passes) {
  60.         stable_sort(data.begin(), data.end(), [&](const T &a, const T &b) -> bool {
  61.             return extract_key(a) < extract_key(b);
  62.         });
  63.         return;
  64.     }
  65.  
  66.     vector<T> buffer(data.size());
  67.     vector<int> counts;
  68.     int bits_so_far = 0;
  69.  
  70.     for (int p = 0; p < passes; p++) {
  71.         int bits = (max_bits + p) / passes;
  72.         int bitmask = (1 << bits) - 1;
  73.         counts.assign((1 << bits) + 1, 0);
  74.  
  75.         for (T &x : data) {
  76.             T_key key = T_key(extract_key(x) - minimum);
  77.             int key_section = int(key >> bits_so_far & bitmask);
  78.             counts[key_section + 1]++;
  79.         }
  80.  
  81.         for (int i = 1; i <= 1 << bits; i++)
  82.             counts[i] += counts[i - 1];
  83.  
  84.         for (T &x : data) {
  85.             T_key key = T_key(extract_key(x) - minimum);
  86.             int key_section = int(key >> bits_so_far & bitmask);
  87.             buffer[counts[key_section]++] = x;
  88.         }
  89.  
  90.         data.swap(buffer);
  91.         bits_so_far += bits;
  92.     }
  93. }
  94. int main() {
  95.     vector<int> a, b;
  96.     for (int i = 1000; i <= 100000000; i *= 10) {
  97.         cout << "Size " << i << " Sorting...." << endl;
  98.         while (a.size() < i) {
  99.             int x = rand() % (1 << 30);
  100.             a.push_back(x);
  101.             b.push_back(x);
  102.         }
  103.         auto t1 = high_resolution_clock::now();
  104.         sortit(a);
  105.         auto t2 = high_resolution_clock::now();
  106.         radix_sort(b);
  107.         auto t3 = high_resolution_clock::now();
  108.         assert(a == b);
  109.  
  110.         cout << "\tTime taken by sortit() -> " << duration_cast<milliseconds> (t2 - t1).count() << "ms" << endl;
  111.         cout << "\tTime taken by radix sort -> " << duration_cast<milliseconds> (t3 - t2).count() << "ms" << endl;
  112.         cout << endl;
  113.     }
  114. }
Advertisement
Add Comment
Please, Sign In to add comment