什么是计数排序
形式上:循环int数组找出最大值,创建一个最大值为数组大小的数组,然后循环需要排序的数组,根据每个数,对应数组下标+1 ,最后循环数组,按照个数从小到大输出,就完成了排序。
思想上:我觉得任何可以转换成数字的都能进行计数排序,比较适合需要排序的东西重复性比较强的的并且容易转换的。
例如:有 红绿青蓝紫 五种球,需要在乱序的arr数组中将这几种球按照 红绿青蓝紫 来排序输出,那我们只要循环一次数组,按照顺序对应数组下标,统计出每个球的个数,然后循环数组输出就行。
时间复杂度:O(n)
限制和缺点:
1 一般来讲,计数排序要求,样本是整数,且范围比较窄
2 一旦要求稍有升级,改写代价增加是显而易见的
代码
package 算法;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class 计数排序 {
public static void countSort(int[] num){
if (num == null || num.length <=1) {
return;
}
//1 找出最大数建立数组
int max =0;
for (int i = 0; i < num.length ; i++) {
max = Math.max(max,num[i]);
}
//2 新建数组 计数
int helpArr[] = new int[max+1];
for (int i = 0; i < num.length; i++) {
helpArr[num[i]]++;
}
//3 输出对应的数
int j = 0;
for (int i = 0; i < helpArr.length; i++) {
//如果>0就一直输出 直到等于0 就输出下一个
while (helpArr[i]-- >0){
num[j++] =i;
}
}
}
private static void sort(int arr[]) {
Arrays.sort(arr);
}
private static int[] getArr(int maxValue,int maxSize ) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random());
}
return arr;
}
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
public static void main(String[] args) {
//生产数组
int[] arr= getArr(1000,1000);
int[] arr2 = copyArray(arr);
//计数排序
countSort(arr);
//默认排序
sort(arr2);
//对数器比较
if (!isEqual(arr,arr2)) {
System.out.println("排序不一样!");
}else{
System.out.println("测试成功!");
}
}
}