算法——排序算法——计数排序优化

在前几篇博客中讲了计数排序的一般方法,理解起来比较简单。但是上一次提到的计数排序只是简单的按照数组下标统计输出了元素的值,并没有真正将原来的数据进行排序。在日常的使用当中,往往会出现相同的数据进行排序,如果还使用前几篇的方法就会发现有些力不从心了,下面来说说如何对计数排序进行优化。

比如说有几个人的成绩分别是:小红:90,小橙:99,小黄:95,小绿:94,小青:95。将这些学生的成绩按照从低到高的顺序进行排序,如果成绩相同按照原来的先后顺序。

首先,还是建立统计数组countArray如下所示:

但是两个95分的学生的成绩不知道顺序如何排列,为了解决这个问题我们队统计数组进行变形,得到如下数组

具体的变化过程是:从统计数组的第二个元素开始,每一个元素的值都是本元素的值加上前面的所有的元素值之和。这样做的目的是把整数放到最终排序的位置上去,比如9对应的元素是5,则99最终应该排在第五位。

下面我们对照成绩表把统计数组中的元素遍历出来,并排序,注意:每遍历一个,就在统计数组中将其值减1,从后往前遍历成绩表,第一个是小青:95,对应的值为4,则表示小青95分应该排在第四位,同时统计数组中下标5对应的值应减1变为3,接着小绿94分,应该排在第二位,同时修改统计数组对应的值为1,下面是小黄95,对应的值为3,应该排在第三位修改下标为2(实际上已经用不到了),下面是小橙99分,对应的值为5,应该排在第五位,修改下标值为4(实际上已经用不到了),最后是小红90分,对应的值为1,应该排在第一位,修改下标的值为0(实际上已经用不到了)。这样通过遍历得到一个新的排序:

设原始数列规模是n,最大最小整数差是m,则时间复杂度为o(n+m),空间复杂度为o(m)。计数排序的缺点是当最大值最小值差距过大时,不适用计数排序,当元素不是整数值,不适用计数排序。

具体java实现代码如下:

import java.util.Arrays;


public class countSort {

	/**
	 * @param args
	 */
	public static int[] countSort(int[] array){
		//定义数组的最大值最小值,并算出差值
		int max = array[0];
		int min = array[0];
		for(int i=1;i<array.length;i++){
			if(array[i]>max){
				max=array[i];
			}
			if(array[i]<min){
				min=array[i];
			}
		}
		int d=max-min;
		//创建统计数组并统计对应元素个数
		int[] countArray = new int[d+1];
		//遍历数组,把统计数组填上
		for(int i1=0;i1<array.length;i1++){
			countArray[array[i1]-min]++;
		}
		//统计数组做变形,后面的元素等于前面的元素之和
		int sum=0;
		for(int j=0;j<countArray.length;j++){
            sum+=countArray[j];
            countArray[j]=sum;
		}
		//倒叙遍历原始数列,从统计数组中找到正确的位置,输出到结果数组
		int[] sorteArray=new int[array.length];
		for(int i=array.length-1;i>=0;i--){
			sorteArray[countArray[array[i]-min]-1]=array[i];
			countArray[array[i]-min]--;
		}
		return sorteArray;
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
           int[] array= new int[]{95,94,91,98,99,90,99,93,91,92};
           int[] sortArray=countSort(array);
           System.out.println(Arrays.toString(sortArray));
	}

}

输出结果:[90, 91, 91, 92, 93, 94, 95, 98, 99, 99]

优化后的版本的计数排序属于一种稳定排序。

猜你喜欢

转载自blog.csdn.net/LOLUN9/article/details/83187950