计数排序
排序的方法又很多种,有效率高的,有简单粗暴的,有令人头疼的。但是今天我要讲的这种排序,我觉得是及其简单的,它的思路很简单,却又比冒泡排序要省略很多的时间,他就是——计数排序。
代码思路:
我们在用数组排序的时候,自然会牵扯到数组的坐标。但是与其用各种递归、分治、回溯、多重循环反复倒腾这些坐标里的数字,何不在坐标本身上下点功夫呢??
是的,比如我们在排序一个数组的时候,一个数组的数字为10,那么我们为何不在坐标为10的位置做一个记号,代表有这么一个数字;
以此种方法,不需要多么复杂的方法,无论是13、24、32……数字,只要在他们对应的坐标下面做一个累加个数,不就是对应的数字个数吗?
剩下的我们只需依次输出对应个数的坐标即可。(话不多说,上代码!)
代码如下:
public class 计数排序初级版 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = gennerateArry(10, 100, 20);
System.out.print("产生的随机数组如下:");
for (int i : arr) {
System.out.print(i + " ");
}
System.out.print("\n调用计数排序后的数组如下:");
countSort(arr);
for (int i : arr) {
System.out.print(i + " ");
}
}
/*
* 生成一个长度为len,最大值为max,最小值为min的随机数组
*/
public static int[] gennerateArry(int len, int max, int min) {
int[] arr = new int[len];
for (int i = 0; i < arr.length; i++) { // 用随机数的方法产生数组内的随机数
arr[i] = (int) (Math.random() * (max - min) + min);
}
return arr;
}
/*
* 初级版计数排序
*/
public static void countSort(int[] arr) {
int max = arr[0];
for (int i : arr) { // 循环找出数组内的最大值,确立数组长度
if (i > max)
max = i;
}
int[] help = new int[max + 1]; // 命名一个长度为max的辅助数组
for (int i : arr) { // 累计原数组对应在辅助数组中下标的个数
help[i]++;
}
int index = 0;
for (int i = 0; i < help.length; i++) {
while (help[i] > 0) {
help[i]--;
arr[index++] = i;
}
}
}
}
总结:
初级版本的计数排序逻辑较为简单,方法自然也简单。但是如果当排列的数字都比较大的时候,比如是0~10000的数字,浪费的空间就很大,所以在后面的程序里,还有对初级版计数排序的升级以及再升级。