importjava.util.Arrays;/*** 计数排序
* 思路:开辟新的空间,空间大小为max(source)+1
* 扫描source,将value作为辅助空间的下标,用辅助空间的该位置元素记录value的个数
* 如 9 7 5 3 1,helper的空间就为10
* 依次扫描,value为9,将helper[9]++,以此类推,完成之后,再去遍历helper
* 如果该位(index)的值为0,说明index不曾在source中出现
* 如果该位(index)的值为 1,说明出现了1次,为2说明出现了两次
* 时间复杂度:扫描一次source,扫描一次helper,复杂度为N+K
* 空间复杂度:如果source里面有个元素较大的,那么开辟的辅助空间较大
* 非原址排序
* 稳定性:相同元素不会出现交叉,非原址都是拷来拷去
* 如果要优化一下空间,可以求出minOf(source),那么helper的长度为(max-min)+1,这样就能短点
* 计数有缺陷,数据较为密集或范围较小时,适用。*/
public classCountSort {static void sort(int[]source){int max = source[0];for (int i = 1; i < source.length; i++) {if (source[i]>max) {
max=source[i];
}
}int []helper = new int[max+1];for(inte:source){
helper[e]++;
}int current = 0; //数据回填的位置
for (int i = 1; i < helper.length; i++) {while(helper[i]>0){
source[current++] =i;
helper[i]--;
}
}
}//保证排序稳定性的版本
public static void sort2(int[] source) {int max = source[0];for (int i = 1; i < source.length; i++) {if (source[i]>max) {
max=source[i];
}
}int []helper = new int[max+1];for (inte : source) {
helper[e]++;
}for (int i = 1; i < helper.length; i++) {
helper[i]+= helper[i - 1];
}int len =source.length;int[] target = new int[len];for (int i = len - 1; i >= 0; i--) {
target[helper[source[i]]- 1] =source[i];
helper[source[i]]--;
}
System.arraycopy(target,0, source, 0, len);
}public static voidmain(String[] args) {int arr[] = new int[10];for(int i=0;i<10;i++){
arr[i]= (int) ((Math.random()+1)*10);
}
System.out.println("排序前:"+Arrays.toString(arr));
sort2(arr);
System.out.println("排序后:"+Arrays.toString(arr));
}
}