各种经典排序算法网上还是比较多的,但是此处实现一个时间复杂度为O(n)(不完全准确,有一定条件)的排序算法。借助JAVA的BitSet来实现,仅提供一个思路。
废话不多说,直接上代码:
public static void sort(){ int[] arr = new int[]{32,21,7,29,18,50}; int max = max(arr); System.out.println(max); BitSet bitSet = new BitSet(max); //初始化bitSet for(int i=0;imax){ max = item; } } return max;}
借助BitSet位存储来对应到具体的某一个排序的值,当然借助别的形式也可以实现,比如new int[] 数组,其长度同样为待排序数组的最大值,但是这样是有限制的,int的最大值是Integer.MAX_VALUE(2147483647),最小值是Integer.MIN_VALUE(-2147483648)。一般情况下是够用。关键是占用空间问题,一个int是4个字节,32位,所以如果指定int的长度,则会需要更大的存储空间。假设指定int长度为5,则存储需要20个字节(相当于640位)。而BitSet指定长度后,是按照位进行数据存储,这样数据就会少很多。所以BitSet常用于存储海量数据。
BitSet可以存储海量数据,但是同时,BitSet会过滤重复的内容,因为它是以true/false来标志的,所以要是对于重复的内容就不能直接使用了,如果非要可能具有相同内容进行排序,可以用以下的方式来实现。
思路:存储某个值出现几次,需要一个存储KV的数据结构。这里使用concurrentHashMap来实现。后面会说明原因。废话不多说,依旧直接上代码
public static void sort(){ int[] arr = new int[]{2,1,7,6,2,3,5,2,6}; Mapcount = new ConcurrentHashMap (arr.length); #增加一个Map对象存储 int max = max(arr); System.out.println(max); BitSet bitSet = new BitSet(max); //初始化bitSet,默认为false,可以不设置 for(int i=0;i > sets = count.entrySet(); for(Map.Entry entry:sets){ if(entry.getValue() == 1){ count.remove(entry.getKey()); #遍历Map,将只出现一次的删除掉 } } int i=0; for(int k=0;k max){ max = item; } } return max;}
可以看到在代码23行和35行执行了map的remove操作,而且在操作之后进行又进行了读操作。由于HashMap是非线程安全的,在进行读写操作执行时,会发生异常,尤其在编码中,如果在线上项目,除非你能确定使用场景,否则一但HashMap操作不当,就会造成各种异常情况,而且可能还不太好排查。而ConcurrentHashMap是线程安全的,而且其内部的加锁机制也不是以前粗暴的加锁方式,也更优雅。有兴趣的同学可以Google下此类的分析或者直接看源码实现。