基数排序

基数排序的复杂度可以写成:O(k(n+2logMax/k),k是维数,n是数据个数,Max是数的最大值。现在需要对10M个32位正整数排序,则可以令k=2,则复杂度为O(2(n+216))=O(n)。具体来说,先按低16位进行第一趟排,然后对结果按高16位排,这种排法与32位同时排是等价的。实现时需要链表,因此辅助开销比较大,而时间比std::sort减少了1半多。

 

 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
#include <bits/stdc++.h>
using namespace std;
#ifndef ONLINE_JUDGE
    #include "local.h"
#endif
#define X first
#define Y second
#define pb(x) push_back(x)
#define mp(x, y) make_pair(x, y)
#define all(a) (a).begin(), (a).end()
#define mset(a, x) memset(a, x, sizeof(a))
#define mcpy(a, b) memcpy(a, b, sizeof(a))
typedef long long ll;
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}

const int maxn = 1e7 + 7;

int seq[maxn];
int top;
struct HashList {
public:
    HashList() { clr(); }
    void clr() {
        sz = 1;
        memset(head, 0, sizeof(head));
    }
    void ins(int val, int pos) {
        hlist[sz] = Node(val, head[pos]);
        head[pos] = sz ++;
    }
    void get(int a[]) {
        for (int i = 0; i < 0x10000; i ++) {
            int h = head[i];
            top = 0;
            while (h) {
                seq[top ++] = hlist[h].val;
                h = hlist[h].next;
            }
            while (top) *a ++ = seq[-- top];
        }
    }
private:
    struct Node {
        int val;
        int next;
        Node(int val = 0, int next = 0)  {
            this->val = val;
            this->next = next;
        }
    };
    Node hlist[maxn];
    int sz;
    int head[1 << 16];
};


int a[maxn];
HashList hl;

void sortint(int *p, int *q) {
    int n = q - p;
    for (int i = 0; i < n; i ++) {
        hl.ins(p[i], p[i] & 0xffff);
    }
    hl.get(p);
    hl.clr();
    for (int i = 0; i < n; i ++) {
        hl.ins(p[i], (p[i] >> 16) & 0xffff);
    }
    hl.get(p);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    int n = 10000000;
    for (int i = 0; i < n; i ++) {
        a[i] = rand() * rand();
    }
    Timer ok;
    sort(a, a + n);
    ok.get();
    ok.start();
    sortint(a, a + n);
    ok.get();
    return 0;
}
原文地址:https://www.cnblogs.com/jklongint/p/4830052.html