基数排序及其基于位操作的优化
第!"卷第#期!$$#年%%月
南&京&工&业&大&学&学&报
’()*+,-(.+,+’/+0)+/12*3/45(.4267+(-(05
189:!"+8:#
+8;:!$$#基数排序及其基于位操作的优化
唐&健,周小跃
(南京工业大学理学院,江苏南京!%$$$<)
摘&要:采用“大!表示法”客观地分析了基数排序算法的时间复杂度,给出了基数排序算法的实现和正确性的证明,并与比较排序算法作了横向的运行时间的对比。对基数排序效率不佳的现状,提出了用位操作方法来优化基数排序,并通过实验证实:优化后的基数排序算法明显提高了排序的运行速度,具有一定的实用价值,使基数排序在一定程度上可与目前最快的快速排序相比拟。
关键词:基数排序;渐进时间复杂度;位操作!
中图分类号:4=>%%&&&文献标识码:,&&&文章编号:%#?%@?#A>(!$$#)$#@$$<<@$A
%&线性时间复杂度的排序算法———基数排序
一般来说,排序算法可分为两种:比较排序算法
和线性时间排序算法。
比较排序算法,是指通过元素间的大小比较来
确定输入序列{"
%,"
!
,…,"
#
}的元素间相对次序的
排序算法。如冒泡排序、直接插入排序、快速排序、
堆排序[%]等。评价一个排序算法是否优秀的重要标准是这个排序算法的比较次数。直接插入排序的时间复杂度为!(#!),改进后的希尔排序的时间复杂度约为!(#%B!),快速排序在平均状态下的时间复杂度为!(#98C
!
#),在特殊状况下(如输入序列本身就是一个有序序列)时间复杂度蜕化为!(#!)。而线性时间排序算法的时间复杂度均为!(#),所以才被称为线性时间排序算法。
基数排序是一种典型的线性时间排序算法[!],文献[!]已证明,通过比较确定两个元素之间相对位置的比较排序算法的时间复杂度下界为
!(#98C
!
#),要想改进这个下界,就必须对输入的数据作某些限制。
!&基数排序的实现和算法正确性的证明[>]基数排序之所以能达到线性的时间复杂度,关键在于它利用了一些“关键字”本身的信息。事实上,大部分排序所用的关键字都是数字,或可轻松地转变为数字。例如,字符串就可看成一个!#进制的特殊数字。例如,给定一串%$进制数:
A"$"%>A!<$!"?<$D">D>!$!#D!%D?"> A"$$%$$!#D>%D A%<"><$!">"%##A>"%$?它们的每一位都只可能在$E<,有%$种可能。基数排序时,首先以每个数字的第%位(个位)为关键字,分别将其分到%$个组中(见表%的“第%次”),个位为$的就插入组$中,个位为%的就插入组%中,依次类推。在插入的时候要特别注意顺序,如A"$"%和A"$$%都应该插入组%,但在原数列中A"$"%在前,所以插入后A"$"%也应该在A"$$%的前面(左边)。全部插好后,再按照从上到下,从左到右的顺序,把表格中的数据读取出来,组成一个新的数列:
A"$"%A"$$%>A!D>!$!$$!<$D">A%<"> <$!">"%##A#D!%D#D>%D<$!"??">>"%$?这个数列的个位数字是不减的。然后再把这个刚得到的数列按照第%次插入的方法,再次插入到%$个组中。这一次插入所依据的关键字为第!位(十位)。插入的结果见表%的“第!次”。同样,再把这些数字按上述方法取出,又得到一个新数列:A"$$%D>!$!>"%$?#D!%D#D>%D>A!"%##A $$!A"$"%<$D">A%<"><$!"><$!"??">、A、D位为关键字,仍按上述方法“插入”、“取
!收稿日期:!$$#@$"@!#
作者简介:唐&健(%<#D@),女,广西桂林人,讲师,主要从事计算与应用数学的研究,2FGHI9:JKLMHNO KHP88:Q8G:QN 万方数据