数据结构和算法-计数排序

1.算法描述

技术排序是一个基于比较的排序算法,该算法于1954由Harold H. Seward 提出。它的优势在于对

一定范围内的整数排序时,它的复杂度为O(n+k)(其中k是整数的范围),快于任何比较排序算

法。当然这是一种牺牲空间换取时间排序的做法,而且当O(K)>O(nlogn)的时候其实效率反而不

如基于比较的排序(基于比较的排序的时间时间复杂度在理论的上的下线是O(nlog(n)),如

归并排序,堆排序)

技术排序是一种适合于最大值和最小值的差值不是很大的排序,也就是说重复的数据会比较多的情况。

具体实现过程如下:

首先遍历整个数组,找到最大的数字。

任何根根据最大的数字创建一个临时数组用于统计每个数字出现的字数,例如temp[i]=m,表示元素i

一共出现了m次。

最后再把临时数组统计的数据从小到大返回到原来的数组中,这样就是有序的。

 2.算法实现

分解1: 找到最大的数字,并且以数字的大小创建一个统计数组

注:这里数组长度应该是max+1;

分解2:

遍历未排序数组获取,统计每一个数字出现的次数根据下标添加到新的统计数组中 

分解3:将统计数组对应的下标的数字返回到排序数组中

代码

package Sort;

public class CountSort {
    public static void main(String[] args) {
        int[] arrs = {0, 2, 1, 3, 0, 2, 0, 1, 1};
        //遍历数组找到最大的值
        int max = arrs[0];

        for (int i = 0; i < arrs.length ; i++) {
            if(arrs[i]>max){
                max=arrs[i];
            }
        }
        //根据最大值创建统一数组
        int[] countArrs=new int[max+1];
        for (int i = 0; i < arrs.length; i++) {
            int k = arrs[i];
            //以k作为下标进行统计
            countArrs[k]++;
        }
        int k=0;//统计数组的下标
        int index=0;//排序数组的下标
        while(k<countArrs.length){
            //判断统计数组中的值是否大于0
            while (countArrs[k]>0){
                //将对应的下标返回到排序数组中
                arrs[index++]=k;
                countArrs[k]--;
            }
            k++;
        }
        for (int i = 0; i < arrs.length; i++) {
            System.out.println(arrs[i]);
        }
    }
}

统计数组优化:

如果待排序的数字很大,那么在创建数组的时候会浪费没有空间,同时也会导致创建的数组太大,

所以需要进行优化;

可以通过使用最大数字减去最小数字求出需要数组的大小。

public class CountSort {
    public static void main(String[] args) {
        int[] arrs = {90, 92, 91, 93, 90, 92, 90, 91, 91};
        //遍历数组找到最大的值
        int max = arrs[0];
        int min = arrs[0];
        for (int i = 0; i < arrs.length ; i++) {
            if(arrs[i] > max){
                max=arrs[i];
            }
            if(arrs[i] < min) {
                min = arrs[i];
            }

        }
        //根据最大值创建统一数组
        int[] countArrs=new int[max-min+1];
        for (int i = 0; i < arrs.length; i++) {
            //获取值的时候需要减去min获取下标
            int k = arrs[i]-min;
            //以k作为下标进行统计
            countArrs[k]++;
        }
        int k=0;//统计数组的下标
        int index=0;//排序数组的下标
        while(k<countArrs.length){
            //判断统计数组中的值是否大于0
            while (countArrs[k]>0){
                //将对应的下标返回到排序数组中
                //需要还原成执行的值,使用下标加上最小值
                arrs[index++]=k + min;
                countArrs[k]--;
            }
            k++;
        }
        for (int i = 0; i < arrs.length; i++) {
            System.out.println(arrs[i]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m0_64005381/article/details/128589578