数据结构排序算法之计数排序 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;
}
}