首页 > 代码库 > 【算法导论学习-014】计数排序(CountingSortTest)

【算法导论学习-014】计数排序(CountingSortTest)

参考:《算法导论》P194页 8.2节 Counting sort

1、Counting sort的条件

   待排序数全部分布在0~k之间,且k是已知数;或者分布在min~max之间,等价于分布在0~max-min之间,max和min是已知数。

2、java 实现

/**
 * 创建时间:2014年8月17日 下午3:22:14 项目名称:Test
 * 
 * @author Cao Yanfeng
 * @since JDK 1.6.0_21 类说明: 计数排序法,复杂度O(n), 条件:所有数分布在0~k,k为已知数
 */
public class CountingSortTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		int[] array = { 7, 2, 5, 9, 1, 2, 7, 3, 0, 3, 4, 7, 8, 6, 6, 2, 0, 0,
				7, 10, 11 };// 0~11之间的整数
		int[] result = countingSort(array, 11);
		for (int i : result) {
			System.out.println(i);
		}
		
	}

	/* 计数排序,注意java数组下标从0开始,所以temp的长度为k+1, */
	public static int[] countingSort(int[] array, int k) {
		int[] temp = new int[k + 1];
		int[] result = new int[array.length];
		for (int i = 0; i < k; i++) {
			temp[i] = 0;
		}

		for (int i = 0; i < array.length; i++) {
			temp[array[i]] = temp[array[i]] + 1;
		}
		for (int i = 1; i < temp.length; i++) {
			temp[i] += temp[i - 1];

		}
		/* temp[array[i]]为所有数字的计数,即数组长度,注意下标为temp[array[i]]-1 */
		for (int i =<span style="font-family: Arial, Helvetica, sans-serif;">array.length-1</span>; i >=0; i--) {
			/*
			 * 关键点:不大于array[i]的元素有temp[array[i]]个,则array[i]的排序位置是temp[array[i]]-1
			 */
			result[temp[array[i]] - 1] = array[i];
			temp[array[i]] = temp[array[i]] - 1;
		}
		return result;
	}

}
****************************************************************************************************************************************************************************************

    对于未知数组,其实可以用O(n)的复杂度先探测到min和max,即k=max-min,数组每个元素都减去min,对新数组进行计数排序,排序后新数组再加上min即可。总的复杂度仍然为O(n)。