首页 > 代码库 > 8.基数排序

8.基数排序

#include <iostream>#include <cmath>#include <cstring>using namespace std; int bits(int t){    int ret = 0;    while(t >= 10)    { ret++; t /= 10; }    return ret + 1;}int find_p(int n, int j){    return (n / (int)pow(10, j - 1)) - (n / (int)pow(10, j)) * 10;}bool Radix_sort(int *a, int n, int k){    int bit = bits(k), *b = new int [n];    int counter[10];        for(int j = 1; j <= bit; j++)    {            memset(counter, 0, sizeof(counter));                for(int i = 0; i < n; i++)            counter[find_p(a[i], j)]++;            for(int i = 1; i < 10; i++)            counter[i] += counter[i - 1];                    for(int i = n - 1; i >= 0; i--)            b[counter[find_p(a[i], j)]-- - 1] = a[i];                    for(int i = 0; i < n; i++)            a[i] = b[i];    }    return true;}int main(){        int n;    cin >> n;    int *num = new int[n];    int *k = &num[0];    for(int i = 0; i < n; i++)    {        cin >> num[i];        if(*k <= num[i]) k = &num[i];    }        Radix_sort(num, n, *k);        for(int i = 0; i < n; i++)        cout << num[i] << " ";    cout << endl;} 

想这个算法的时候,原本想通过二进制来排序(二进制的某位的数字比较容易get: x & 1 << i 即可), 但这样子的话需要循环30次(假设为int类型), 虽说影响不大但每次的移动次数过多,效率上反而可能不如用其他进制了(大致的估计, 并没推导过)。 排序部分只要时一种稳定排序即可, 计数排序反而成了比较好的选择(计数排序容易MLE的弊端在基数排序中得到了屏蔽)。并且计数排序为非比较性排序,效率上比其他比较排序高了很多。

算法的时间复杂度: O(bits*(n + 10)) = O(bits * n) = O(n) (Exc Me???) : 解释:bits为数在进制下的位数, 10是指10进制

 

代码缺陷:

  a.为节省内存用了new造成代码比较凌乱

  b.总感觉find_p() 在调用或者内部上有些啰嗦, 应当可以省略

  c.代码的关键部分连着三个 ‘-’ 很奇葩啊有没有....

8.基数排序