标签:
16. 蛤蟆的数据结构进阶十六排序实现之基数排序
本篇名言:“社会犹如一条船 ,每人都要有掌舵的准备。--易卜生”
我们来看下基数排序。
欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47760601
基数排序(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
观察可以看到,此时原无序数据序列已经排序完毕。如果排序的数据序列有三位数以上的数据,则重复进行以上的动作直至最高位数为止。
主要部分代码:
首先申请一个存放基数的空间,空间大小为元素个数大小总和。
初始化倍数基数为1.
处理第一次循环的时候,基数为10 (即nRadixBase).
将处理的数组放入到nDataRadix中(获取元素中的其中一个值)。
nDataRadix[i]= nPData[i] % nRadixBase;
nDataRadix[i] /= nRadixBase / 10;
然后调用RadixCountSort函数进行分配。
处理基数为100,处理百位的数。以此循环。
最后释放申请的辅助空间。
最后如下图1:
分配保存计数的个数的数组(个数由所调函数传入)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
#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-1到0的顺序排序的,是为了使排序稳定。
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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/notbaron/article/details/47760601