随感而发

杂七杂八

统计

留言簿(13)

阅读排行榜

评论排行榜

基数排序

今天学了基数排序,据说他的时间复杂度也是O(n),他的思路就是:
没有计数排序那么理想,我们的数据都比较集中,都比较大,一般是4,5位。基本没有小的数据。
那我们的处理很简单,你不是没有小的数据嘛。我给一个基数,例如个位,个位都是[0-10)范围内的。先对他进行归类,把小的放上面,大的放下面,然后个位排好了,在来看10位,我们也这样把小的放上面,大的放下面,依次内推,直到最高位排好。那么不就排好了吗?我们只需要做d(基数个数)的循环就可以了。时间复杂度相当于O(d * n) 因为d为常量,例如5位数,d就是5.所以近似为O(n)的时间复杂度。这次自己写个案例:

最初的数据

排好个位的数据

排好十位的数据

排好百位的数据

981

981

725

129

387

753

129

387

753

955

753

456

129

725

955

725

955

456

456

753

725

387

981

955

456

129

387

981

这里只需循环3次就出结果了。

<!--[if !supportLists]-->3.       <!--[endif]-->但是注意,我们必须要把个位排好。但是个位怎么排呢?这个是个问题。书上说的是一叠一叠的怎么合并,我是没有理解的。希望知道的有高手教我一下。

我是用的一个计数排序来排各位的,然后排十位。效率应该也低不到哪里去。呵呵。。

思路就这样咯。奉上源代码:

 

#include <stdio.h>
#include 
<stdlib.h>

//计数排序,npRadix为对应的关键字序列,nMax是关键字的范围。npData是具体要
//排的数据,nLen是数据的范围,这里必须注意npIndex和npData对应的下标要一致
//也就是说npIndex[1] 所对应的值为npData[1]
int RadixCountSort(int* npIndex, int nMax, int* npData, int nLen)
{
    
//这里就不用说了,计数的排序。不过这里为了是排序稳定
    
//在标准的方法上做了小修改。

    
int* pnCount  = (int*)malloc(sizeof(int)* nMax);        //保存计数的个数
    for (int i = 0; i < nMax; ++i)
    {
        pnCount[i] 
= 0;
    }
    
for (int i = 0; i < nLen; ++i)    //初始化计数个数
    {
        
++pnCount[npIndex[i]];
    }

    
for (int i = 1; i < 10++i)  //确定不大于该位置的个数。
    {
        pnCount[i] 
+= pnCount[i - 1];
    }

    
int * pnSort  = (int*)malloc(sizeof(int* nLen);    //存放零时的排序结果。

    
//注意:这里i是从nLen-1到0的顺序排序的,是为了使排序稳定。
    for (int i = nLen - 1; i >= 0--i)
    {
        
--pnCount[npIndex[i]];        
        pnSort[pnCount[npIndex[i]]] 
= npData[i];
    }

    
for (int i = 0; i < nLen; ++i)        //把排序结构输入到返回的数据中。
    {
        npData[i] 
= pnSort[i];
    }
    free(pnSort);                        
//记得释放资源。
    free(pnCount);
    
return 1;
}

//基数排序
int RadixSort(int* nPData, int nLen)
{
    
//申请存放基数的空间
    int* nDataRadix    = (int*)malloc(sizeof(int* nLen);

    
int nRadixBase = 1;    //初始化倍数基数为1
    bool nIsOk = false//设置完成排序为false

    
//循环,知道排序完成
    while (!nIsOk)
    {
        nIsOk 
= true;
        nRadixBase 
*= 10;
        
for (int i = 0; i < nLen; ++i)
        {
            nDataRadix[i] 
= nPData[i] % nRadixBase;
            nDataRadix[i] 
/= nRadixBase / 10;
            
if (nDataRadix[i] > 0)
            {
                nIsOk 
= false;
            }
        }
        
if (nIsOk)        //如果所有的基数都为0,认为排序完成,就是已经判断到最高位了。
        {
            
break;
        }
        RadixCountSort(nDataRadix, 
10, nPData, nLen);
    }

    free(nDataRadix);

    
return 1;
}

int main()
{
    
//测试基数排序。
    int nData[10= {123,5264,9513,854,9639,1985,159,3654,8521,8888};
    RadixSort(nData, 
10);
    
for (int i = 0; i < 10++i)
    {
        printf(
"%d ", nData[i]);
    }
    printf(
"\n");

    system(
"pause");
    
return 0;
}

 


posted on 2009-04-24 21:36 shongbee2 阅读(13350) 评论(2)  编辑 收藏 引用 所属分类: 数据结构和算法

评论

# re: 基数排序[未登录] 2012-06-02 10:01 MICHAEL

你的这个程序有一定的问题
比如这组数据:
int nData[10] = {1046,2084,9046,12074,56,7026,8099,17059,33,1};
  回复  更多评论   

# re: 基数排序 2013-06-28 13:49 hum

试了下,确实有点问题,修改一下就好了。
修改前
if (nDataRadix[i] > 0)
{
nIsOk = false;
}
修改后:
if (nPData[i]/nRadixBase > 0)
{
nIsOk = false;
}  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理