非比较排序--基数排序实现给字符串数组排序

1.计数排序的局限性



    前面学习了计数排序,能够实现O(n+k)的时间复杂度,可是他有很大的局限性,最大的问题就是若是最大值和最小值之间相差太大的话,那么会浪费掉很大的空间,好比要排序{1,10000,99,64,120}咱们能够根据以前的计算公式最大值减去最小值加一获得计数数组的长度,那么计数数组长度就应该是10000,可是实际上咱们只存放了5个数据,中间浪费了极大的空间,因此在使用计数排序时,应该根据本身的实际状况来决定。java

    好比咱们要对电话号码进行一个排序,显然用计数排序是很浪费空间的,同时由于时间复杂度为O(n+k),可是n太大时,实际上他不必定比快速排序或者归并排序要快



2.基数排序



    什么是基数排序呢?基数排序和计数排序都是桶排序的一种思想,基数是一种关键字排序,例如咱们有这样的一组数据{421,326,266,157,222,414}咱们首先拿到每个数的最后一位,也就是个位,而后进行排序,排序好后再取出十位进行排序,最后拿出百位来进行排序便可,而其中咱们每次取的位就是对关键字的操做。算法





    ps:须要注意的是咱们第一次根据个位排序时操做的是原数组,而根据十位排序的时候是在以前个位排好的基础上进行排序,同理百位则是对十位排好后的进行排序。数组


    看到这儿聪明的你确定会问,若是位数不一致怎么办?好比有的是3位数,有的是4位数,甚者有可能还有2位数以及1位数,其实这个很好解决咱们只须要找到最大的那个数,而后根据最大的那个数来决定排几回,其他不足的在前面添0,好比最大222,其中又有1位数的,2位数的,那么就在2位数前面加一个0,而1位数则在前面加2个0便可。


java代码实现以下微信




    实际上咱们这个代码已经实现了自动加0的功能,咱们用Math.pow(10,i)来产生10的i平方,而后拿到原数组中的值除以获得的平方数再求余10,若是是1除以1000是0,再用0取余10因此仍是0,因此会自动补0。app



2.基数排序时间空间复杂度



    咱们来看看时间复杂度和空间复杂度,实际上找出最大数的位数为多少位,这一步应该是在外面计算好了传递进来的,他并不属于基数排序里面的。less

    

    最外层一共循环了d次,其中d就是咱们最大数的位数,而循环体内咱们对原数组遍历了2次,因此是2n,而计数数组执行了一次就是k,也就是O(d*(2n+k)),而后咱们去掉一个常数阶,能够获得时间复杂度为O(d*(n+k)),那空间复杂度又是多少呢?根据咱们写的代码,咱们一共定义了一个计数数组和一个结果数组因此是O(n+10),而后去掉一个常数阶能够获得空间复杂度为O(n)。且基数排序是一个稳定的排序算法。编辑器



2.基数排序字符串排序



    如何用基数排序实现对字符串排序呢?咱们仍是使用一样的方式例如字符串数{"abc","def","sxf","sss","cbh"},咱们拿到最后一位放入对应的位置,好比abc,当咱们拿到c时这个时候因为是字符串你是根本不知道放那个位置的,因此咱们能够将他变成char的字符,因为c字符对应的ASCll是99,因此咱们存放在99的位置就行,固然若是字符串位数不一致,同理咱们能够在前面补一个比A的ASCll还小的值便可。字符串排序重点就是要借助ASCll来实现学习



Java代码实现以下spa









本文分享自微信公众号 - 大猫的Java笔记(damaoJava)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。.net

相关文章
相关标签/搜索