码迷,mamicode.com
首页 > 编程语言 > 详细

8.基数排序

时间:2016-09-09 23:50:04      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:

#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.基数排序

标签:

原文地址:http://www.cnblogs.com/QQ-1615160629/p/5858428.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!