算法导论——计数排序

/**
	 * 计数排序
	 * 
	 * 不用比较的排序算法,时间可以突破O(NlgN)
	 * 
	 * 时间复杂度O(N),稳定
	 * 
	 * 适用于所有需要排序的数据值都比较小的时候,也就是说下面传递的max值一般不会大到哪里去
	 * 
	 */
	@Test
	public void countingSort(){
		//待排序的分数
		int[] scores={77,92,85,98,62,100,68,77,92,100};
		
		//将最大值传入以作为计数上限
		countingSort(scores,100);
		
		System.out.println(Arrays.toString(scores));
	} 

	private void countingSort(int[] scores, int max) {
		int[] count=new int[max+1];
		
		//利用count数组对scores中每个元素计数
		for(int i=0;i<scores.length;i++){
			count[scores[i]]++;
		}
		
		//统计<=i的元素的个数
		for(int i=1;i<count.length;i++){
			count[i]+=count[i-1];
		}
		
		//创建大小和scores数组一样的数组,用来存入已拍好序的数组元素
		int[] copy=new int[scores.length];
		
		//逆序遍历可以保证计数排序的稳定性
		for(int i=copy.length-1;i>=0;i--){
			//count[i]表示小于等于i元素的数量,就是i元素的位置,那么count[scores[i]]-1表示小于等scores数组第i号元素的位置
			//这里就将它插入到copy数组的合适的位置就行
			copy[count[scores[i]]-1]=scores[i];
			//由于可能存在重复元素,所以放入一个元素之后,要将它的count-1,这样才能保证下一个相同元素能放到前面一格
			count[scores[i]]--;
			
			//如果要采用简写,可以考虑copy[--count[scores[i]]]=scores[i],以上写法为了方便理解
		}
		
		//将copy复制到scores上
		for(int i=0;i<copy.length;i++){
			scores[i]=copy[i];
		}
	}



你可能感兴趣的:(算法导论,计数排序)