7. 计数排序
思想
计数排序,不再依赖元素的比较,而是通过计数的方式,来进行排序。
比如,你知道成绩比你高的有5个人,那么你是多少名呢?计数排序就是采用这种思想。
计数排序,为每一个元素设置一个计数,然后进行计数排序。
从这个思想上来看,计数排序会使用到复制的空间,而且辅助空间的数量为 待排序数组的最大值-最小值+1。
从这个分析上,可以知道计数排序适用于 小范围的排序,就是说待排序的数组,最大小值的差值不能太大。
实现
import java.util.Arrays;
public class CountSort {
public static void main(String[] args) {
int[] nums = {4, 6, 7, 2, 7, 8, 20, 2};
int max_value = nums[0], min_value = nums[0];
for (int i = 0; i < nums.length; i++) {
max_value = Math.max(max_value, nums[i]);
min_value = Math.min(min_value, nums[i]);
}
countSort(nums, max_value-min_value+1, min_value);
System.out.println(Arrays.toString(nums));
}
public static void countSort(int[] nums, int count_value, int min_value){
int[] count_array = new int[count_value];
for (int i = 0; i < nums.length; i++) {
count_array[nums[i]-min_value]++;
}
System.out.println(Arrays.toString(count_array));
for (int i = 0, index = 0; i < count_array.length; i++) {
int count = count_array[i];
while(count--!=0) nums[index++] = min_value+i;
}
}
}
复杂度
首先,第一次遍历待排序数组,确定最大值及最小值,利用此创建计数数组。时间复杂度为O(n)
之后遍历待排序数组,将相应位置的值放入计数数组,时间复杂度为O(n)
最后遍历计数数组,将其中计数值放入待排序数组,时间复杂度为O(m) m为最大小值的差值
所以,总的时间复杂度为O(m+n)
空间复杂度为O(m)