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

16. 蛤蟆的数据结构进阶十六排序实现之基数排序

时间:2015-08-18 22:49:54      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

16. 蛤蟆的数据结构进阶十六排序实现之基数排序

本篇名言:“社会犹如一条船 ,每人都要有掌舵的准备。--易卜生”

我们来看下基数排序。

 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47760601

 

1.  基数排序

基数排序(radix sort)属于“分配式排序”(distributionsort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

         基数排序不需要进行记录关键字间的比较。基数排序是 一种借助多关键字排序的思想对逻辑关键字进行排序的方法。

基数排序是通过“分配”和“收集”过程来实现排序。

假设有欲排数据序列如下所示:

73  22  93  43 55  14  28  65  39  81

首先根据个位数的数值,在遍历数据时将它们各自分配到编号0至9的桶(个位数值与桶号一一对应)中。

分配结果(逻辑想象)如下图所示:

技术分享

分配结束后。接下来将所有桶中所盛数据按照桶号由小到大(桶中由顶至底)依次重新收集串起来,得到如下仍然无序的数据序列:

81  22  73  93 43  14  55  65  28  39

接着,再进行一次分配,这次根据十位数值来分配(原理同上),分配结果(逻辑想象)如下图所示:

技术分享

分配结束后。接下来再将所有桶中所盛的数据(原理同上)依次重新收集串接起来,得到如下的数据序列:

14 22  28  39  43  55  65  73  81  93

观察可以看到,此时原无序数据序列已经排序完毕。如果排序的数据序列有三位数以上的数据,则重复进行以上的动作直至最高位数为止。

 

 

 

2.  代码实现

主要部分代码:

首先申请一个存放基数的空间,空间大小为元素个数大小总和。

         初始化倍数基数为1. 

         处理第一次循环的时候,基数为10 (即nRadixBase).

         将处理的数组放入到nDataRadix中(获取元素中的其中一个值)。

         nDataRadix[i]= nPData[i] % nRadixBase;

           nDataRadix[i] /= nRadixBase / 10;

         然后调用RadixCountSort函数进行分配。

处理基数为100,处理百位的数。以此循环。

 

 

最后释放申请的辅助空间。

最后如下图1:

技术分享

2.1         RadixCountSort

分配保存计数的个数的数组(个数由所调函数传入)pnCount。

分配保存存放零时的排序结果的数组pnSort。                   

初始化个数数组pnCount。

pnCount记录数据各元素当前处理位拥有的数量。

处理前数组:{73,22,93, 43,55,14,28,65, 39, 81};

npIndex数组(即元素的余数数组):3 ,2,3,3,5,4,8,5,9,1

当第一轮处理完毕后

余数为0:

余数为1:81

余数为2:22

余数为3:73 93 43

余数为4:14

余数为5:55 65

余数为6:

余数为7:

余数为8:28

余数为9:39

pnCount :0,1,2,5,6,8,8,8,9,10

处理完毕后得到数组:81,22,73,93,43,14,55,65,28,39

按照个位数大小进行了排序。

将一轮处理完的数组赋值给最后的数组。

最后释放pnSort,pnCount

3.  源码

#include<stdio.h>

#include<stdlib.h>

#defineN10

int RadixCountSort(int*npIndex, int nMax, int* npData, int nLen)

{

    int*pnCount  = (int*)malloc(sizeof(int)*nMax);       //保存计数的个数

    inti=0;

 

    for(i = 0; i < nMax; ++i)

    {

       pnCount[i] = 0;

    }

    for(i = 0; i < nLen; ++i)   //初始化计数个数

    {

       ++pnCount[npIndex[i]];

    }

 

    for(i = 1; i < 10; ++i)  //确定不大于该位置的个数。

    {

       pnCount[i] += pnCount[i - 1];

    }

 

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

 

    //注意:这里i是从nLen-10的顺序排序的,是为了使排序稳定。

    for(i = nLen - 1; i >= 0; --i)

    {

       --pnCount[npIndex[i]];       

       pnSort[pnCount[npIndex[i]]] =npData[i];

    }

 

    for(i = 0; i < nLen; ++i)       //把排序结构输入到返回的数据中。

    {

        npData[i]= pnSort[i];

    }

   free(pnSort);                       //记得释放资源。

    free(pnCount);

    return1;

}

 

//基数排序

int RadixSort(int*nPData, int nLen)

{

    //申请存放基数的空间

    int*nDataRadix    = (int*)malloc(sizeof(int)*nLen);

 

    intnRadixBase = 1;    //初始化倍数基数为1

    intnIsOk = 0; //设置完成排序为false

    inti;

    //循环,知道排序完成

    while(nIsOk==0)

    {

        nIsOk= 1;

       nRadixBase *= 10;

        for(i = 0; i < nLen; ++i)

        {

           nDataRadix[i] = nPData[i] %nRadixBase;

           nDataRadix[i] /= nRadixBase / 10;

            if(nDataRadix[i] > 0)

            {

               nIsOk = 0;

            }

        }

        if(nIsOk==1)        //如果所有的基数都为0,认为排序完成,就是已经判断到最高位了。

        {

            break;

        }

       RadixCountSort(nDataRadix, 10,nPData, nLen);

    }

 

   free(nDataRadix);

 

    return1;

}

int main(intargc,char *argv[])

{

    inti=0;

    intj;

         j = N;

         intnData[N]={73,22,93, 43, 55,14,28,65, 39, 81};

   RadixSort(nData, j);

 

    printf("基数排序法排序后:\n");

    for(i = 0; i < j; ++i)

    {

       printf("%d ", nData[i]);

    }

    printf("\n");

    return0;

}

 

 

 

 

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

16. 蛤蟆的数据结构进阶十六排序实现之基数排序

标签:

原文地址:http://blog.csdn.net/notbaron/article/details/47760601

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