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

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-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;

}

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

时间: 2024-08-03 21:10:51

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

15. 蛤蟆的数据结构进阶十五排序实现之堆排序

15. 蛤蟆的数据结构进阶十五排序实现之堆排序 本篇名言:"谁要是游戏人生 ,他就一事无成 ; 谁不能主宰自己 ,永远是一个奴隶.--歌德" 继续来看下堆排序. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47733553 1.  堆排序 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆分为大根堆和小根堆,是完全二叉树

14. 蛤蟆的数据结构进阶十四排序实现之简单选择排序

14. 蛤蟆的数据结构进阶十四排序实现之简单选择排序 本篇名言:"即是我们是一支蜡烛也应该 " 蜡烛成灰泪始干 " 即使我们只是一根火柴也要在关键时刻有一次闪耀即使我们死后尸骨都腐烂了解也要变成磷火在荒野中燃烧. -- 艾青" 继续来看什么是简单选择排序. 欢迎转载,转载请标明出处: 1.  简单选择排序 设所排序序列的记录个数为n.i取1,2,-,n-1,从所有n-i+1个记录(Ri,Ri+1,-,Rn)中找出排序码最小的记录,与第i个记录交换.执行n-1趟后就完

18. 蛤蟆的数据结构进阶十八排序实现之快速排序

18. 蛤蟆的数据结构进阶十八排序实现之快速排序 本篇名言:"一个人做点好事并不难,难的是一辈子做好事,不做坏事.--毛泽东" 我们最后来看下快速排序,以及各个排序之间的一些信息汇总. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47817933 1.  快速排序 快速排序由C. A. R.Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分

12. 蛤蟆的数据结构进阶十二排序实现之直接插入法

12. 蛤蟆的数据结构进阶十二排序实现之直接插入法 本篇名言:"路是脚踏出来的 ,历史是人写出来的,人的每一步行动都在书定自己的历史. --吉鸿昌" 接下来看下直接插入法的实现. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47687631 1.  直接插入法 直接插入排序(straightinsertion sort) 每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序. 第一趟比较前两

19. 蛤蟆的数据结构进阶十九外部排序相关概念

19. 蛤蟆的数据结构进阶十九外部排序相关概念 本篇名言:"一个人最怕不老实,青年人最可贵的是老实作风. "老实 " 就是不自欺欺人,做到不欺骗人家容易,不欺骗自己最难. "老实作风 " 就是脚踏实地,不占便宜.世界上没有便宜的事,谁想占便宜水就会吃亏. --徐特立" 之前我们学习的排序都是内部排序的,接下去来看下外部排序. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47

10. 蛤蟆的数据结构进阶十排序相关概念

10. 蛤蟆的数据结构进阶十排序相关概念 本篇名言:"生,亦我所欲也:义,亦我所欲也:二者不可得兼,舍生而取义者也.--孟轲" 接下去我们将来看下排序相关的知识. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47381339 1.  排序 排序是什么? 将一组杂乱无章的记录按一定规律顺序排列起来. 什么排序方法是稳定的?什么是不稳定的? 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记

6. 蛤蟆的数据结构进阶六之二叉树排序树

6. 蛤蟆的数据结构进阶六之二叉树排序树 本篇名言:"有些人因为贪婪,想得更多的东西,却把现在所有的也失掉了. -- 伊索" 关于理论知识已经在上篇中进行描述,这篇我们主要来看下如何是实现二叉排序树. 欢迎转载,转载请标明出处: 1.  二叉排序树的定义 二叉排序树(BinarySort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树: ①若它的左子树非空,则左子树上所有结点的值均小于根结点的值: ②

17. 蛤蟆的数据结构进阶十七排序实现之归并排序

17. 蛤蟆的数据结构进阶十七排序实现之归并排序 本篇名言:"人生不是一种享乐 ,而是一桩十分沉重的工作.-- 列夫 . 托尔斯泰" 我们来看下归并排序. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47790163 1.  归并排序 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序列:即先使每个

13. 蛤蟆的数据结构进阶十三排序实现之希尔排序法

13. 蛤蟆的数据结构进阶十三排序实现之希尔排序法 本篇名言:"一个人光溜溜的到这个世界来 ,最后光溜溜的离开这个世界而去 , 彻底想起来 , 名利都是身外物 ,只有尽一人的心力 , 使社会上的人多得他工作的裨益 ,是人生最愉快的事情.--邹韬奋" 下面是希尔排序法了. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47706135 1.  希尔排序 希尔排序(ShellSort)是插入排序的一种.也称缩小增量排序