《算法导论》学习心得(六)—— 计数排序(Java)

       计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。基本思想是:统计一个数序列中小于某个元素a的个数为n,则直接把该元素a放到第n+1个位置上。当然当过有几个元素相同时要做适当的调整,因为不能把所有的元素放到同一个位置上。计数排序假设输入的元素都是0到k之间的整数原理如图所示(图引自http://www.cnblogs.com/kaituorensheng/archive/2013/02/23/2923877.html):




具体代码实现:

private static int[] countingSort(int[] array,int biggestCount) {
		int[] resultArray = new int[array.length];//结果输出数组
		int[] countArray = new int[biggestCount];//构造计数数组
		for(int i=0;i<countArray.length;i++)
		{
			countArray[i] = 0;//初始化,虽然java数组默认的是整形,但是这是算法的一个步骤
		}
		for(int i=0;i<array.length;i++)
		{
			countArray[array[i]] = countArray[array[i]]+1;//统计0···biggestCount出现的次数
		}
		/******************第一种实现方式(保证了数组的稳定性)*********************/
		for(int j=1;j<biggestCount;j++)
		{
			countArray[j] = countArray[j]+countArray[j-1];//统计每一个数在数组中的下标
		}
		for(int m = array.length-1;m>=0;m--)
		{
			resultArray[countArray[array[m]]-1] = array[m];//找到这个数应该在的位置,并且把这个值放在正确的位置上!
			countArray[array[m]] = countArray[array[m]]-1;//出现一次需要减一,相当于再出现相同的数时该数在数组中的下标向前移动一位
		}
		/******************第二种实现方式(不能保证数组的稳定性)*********************/
		/*int index=0;
		for(int i=0;i<biggestCount;i++)
		{
			while(countArray[i]>0)
			{
				resultArray[index]=i;
				index++;
				countArray[i] = countArray[i]-1;
			}
		}*/
		return resultArray;
	}
完整代码:

package com.tangbo;

import java.util.Random;
import java.util.Scanner;

public class CountingSort {
	static Scanner scanner;
	static Random random = new Random();
	static int biggestNum = 25;
	public static void main(String[] args) {
		int[] array = productArray();
		print(countingSort(array, biggestNum));
	}
	private static int[] countingSort(int[] array,int biggestCount) {
		int[] resultArray = new int[array.length];//结果输出数组
		int[] countArray = new int[biggestCount];//构造计数数组
		for(int i=0;i<countArray.length;i++)
		{
			countArray[i] = 0;//初始化,虽然java数组默认的是整形,但是这是算法的一个步骤
		}
		for(int i=0;i<array.length;i++)
		{
			countArray[array[i]] = countArray[array[i]]+1;//统计0···biggestCount出现的次数
		}
		/******************第一种实现方式(保证了数组的稳定性)*********************/
		for(int j=1;j<biggestCount;j++)
		{
			countArray[j] = countArray[j]+countArray[j-1];//统计每一个数在数组中的下标
		}
		for(int m = array.length-1;m>=0;m--)
		{
			resultArray[countArray[array[m]]-1] = array[m];//找到这个数应该在的位置,并且把这个值放在正确的位置上!
			countArray[array[m]] = countArray[array[m]]-1;//出现一次需要减一,相当于再出现相同的数时该数在数组中的下标向前移动一位
		}
		/******************第二种实现方式(不能保证数组的稳定性)*********************/
		/*int index=0;
		for(int i=0;i<biggestCount;i++)
		{
			while(countArray[i]>0)
			{
				resultArray[index]=i;
				index++;
				countArray[i] = countArray[i]-1;
			}
		}*/
		return resultArray;
	}
	static void print(int []array)//打印函数
	{
		for(int i=0;i<array.length;i++)
		{
			System.out.print(array[i]+" ");
		}
		System.out.println();
	}
	static int [] productArray()//生成一个数组
	{
		int arrayayLength=0;
		System.out.println("请输入数组长度:");
		scanner = new Scanner(System.in);
		arrayayLength = scanner.nextInt();
		int [] arrayayTemp = new int[arrayayLength];
		for (int i = 0; i < arrayayLength; i++) {
			arrayayTemp[i]=random.nextInt(biggestNum);
			System.out.print(arrayayTemp[i]+" ");
		}
		System.out.println();
		return arrayayTemp;
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值