计数排序假设n个输入元素中的每一个都是在0到k区间的一个整数,其中k为某个整数,当k=O(n)时,排序的运行时间为θ(n)。
计数排序的基本思想是:对每一个输入元素x,确定小于x的元素个数。利用这一信息,就可以直接把x放到它在输出数组中的位置上。例如,如果有17个元素小于x,则x就应该在第18个输出位置上。根据这个思想,对于一个A[1…n]的数组,计数排序可按如下步骤进行:
- 定义一个数组B[1…n],用于存放最终排序的A中的元素;
- 计算出数组A中的最大值k;
- 定义数组C[0…k],用于存放A中元素的计数;
- 对数组A中的元素进行计数,并将A中元素的计数放到C中以该元素为下标的位置;
- 计数完成后,对C中的元素进行加总,使得C[i]=C[i]+C[i-1];
- 最后,根据C中的结果将A中对应的元素放置到B中对应的位置。
下图展示了计数排序的运行过程:
java实现如下:
/*** 计数排序** @param nums 待排序数组*/public void countingSort(int[] nums) {// 定义临时数组用于存放排序后的结果int[] tempResult = new int[nums.length];// 计算数组中的最大值,用于定义计数数组int max = Integer.MIN_VALUE;for (int num : nums) {max = Math.max(max, num);}// 定义计数数组,并开始计数int[] count = new int[max + 1];for (int num : nums) {count[num] += 1;}// 计算对于数组中的每一个数字k,小于等于k的个数for (int j = 1; j <= max; j++) {count[j] += count[j - 1];}// 将每个元素放到结果数组中正确排序的位置for (int j = nums.length - 1; j >= 0; j--) {tempResult[count[nums[j]] - 1] = nums[j];count[nums[j]]--;}// 将结果数组复制到原数组System.arraycopy(tempResult, 0, nums, 0, nums.length);}