数据结构排序算法之计数排序 Java

数据结构排序算法之计数排序 Java

计数排序:
计数排序是一个非基于比较的排序算法,而是利用数组下标来确定元素的正确位置。
用辅助数组对数组中出现的数字计数,元素转下标,小标转元素。
假设元素均大于等于0,依次扫描原数组,将元素值k记录在辅助数组的k位上。

下面我会分别介绍:
1、基础计数排序,只适用于正整数
2、改进计数排序,可适用所有数
3、在第二种上进行优化的排序

代码:
主代码块:

import java.util.Scanner;

public class 计数排序
{

	public static void main(String[] args) {
		// 输入20个随机整数
		// 输入数组长度,随机数组的最大值,最小值
		Scanner sc = new Scanner(System.in);
		int length = sc.nextInt();
		int min = sc.nextInt();
		int max = sc.nextInt();
		int[] arr = Util.getRandomArr(length, min, max);
		// 原始数组
		Util.show(arr);
		// 调用基础计数排序,不能有负数
		countSort1(arr);
		// 调用改进版,计数排序
		countSort2(arr);
		// 调用优化版,计数排序		
		// 输出
		Util.show(countSort3(arr));
	}

	// 基础计数排序
	public static void countSort1(int[] arr) {
		// 找到arr的最大值
		int max = arr[0];
		for (int i : arr)
		{
			if (max < i)
			{
				max = i;
			}
		}
		// 创建计数数组长度为最大值+1
		int[] countArr = new int[max+1];
		for (int i : arr)
		{
			countArr[i]++;
		}
		// arr1的下标还原到countArr数组中
		for (int i = 0, k = 0; i < countArr.length; i++)
		{
			for (int j = 0; j < countArr[i]; j++)
			{
				arr[k++] = i;
			}
		}
	}

	// 改进版 计数排序,利用区间,负数可行 ,1 2 3 50 9999 这样就不是很快
	public static void countSort2(int[] arr) {
		// 找到最小值和最大值
		int max = arr[0];
		int min = arr[0];
		for (int i : arr)
		{
			if (max < i)
			{
				max = i;
			}
			if (min > i)
			{
				min = i;
			}
		}
		//创建计数数组
		int[] countArr=new int[max-min+1];
		for (int i : arr)
		{
			countArr[i-min]++;
		}
		//回填,还原到arr的数组
		for (int i = 0,j=0; i < countArr.length; i++)
		{
			for (int j2 = 0; j2 < countArr[i]; j2++)
			{
				arr[j++]=i+min;
			}
		}
	}
	//优化版 计数排序 
	public static int[] countSort3(int[] arr){
		// 找到最小值和最大值
		int max = arr[0];
		int min = arr[0];
		for (int i : arr)
		{
			if (max < i)
			{
				max = i;
			}
			if (min > i)
			{
				min = i;
			}
		}
		//创建计数数组
		int[] countArr=new int[max-min+1];
		for (int i : arr)
		{
			countArr[i-min]++;
		}
		//对计数数组的元素进行累加,累加的规则是前一个元素的值+当前元素
		for (int i = 1; i < countArr.length; i++)
		{
			countArr[i]+=countArr[i-1];
		}
		//创建一个数组存储最终有序数列
		int[] sortArr=new int[arr.length];
		//回填
		for (int i = arr.length-1; i >=0; i--)
		{
			sortArr[countArr[arr[i]-min]-1]=arr[i];
			countArr[arr[i]-min]--;
		}
		return sortArr;
	}
}

封装代码块:

import java.util.Arrays;
import java.util.Random;


public class Util
{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int [] arr=getRandomArr(10, 20, 50);
		show(arr);
		swap(arr, 2, 9);
		show(arr);
	}
	/*
	 *生成随机数 
	 * 参数:
	 * length:数组长度
	 * min: 最小值
	 * max:最大值
	 * 返回值:随机数组
	 */
	public static int[] getRandomArr(int length,int min,int max) {
		//创建数组
		int[] arr= new int[length];
		//每一个元素赋值
		for (int i = 0; i < arr.length; i++)
		{
			arr[i]=new Random().nextInt(max-min+1)+min;
		}
		//返回arr
		return arr;
	}
	/*
	 * 输出数组元素
	 * arr:输出的数组
	 */
	 public static void show(int[] arr){
		 System.out.println(Arrays.toString(arr));
	 }
	 /*
	  * 交换数组两个下标元素的值
	  */
	 public static void swap(int[] arr,int i,int j){
		int temp;
		temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值