• 排序之计数排序


    计数排序并非一种基于比较进行的排序,它是计算一个序列中的值在正常排好序中的序列所处的位置,怎么求解一个数的位置呢?就是利用下脚标进行求解,新建一个数组resu[],数组的长度要比序列中的最大值大1,数组中的值全部初始化为0,然后遍历原序列,将原序列的值i作为新建数组resu[]的下脚表,对resu[i]++操作,这样就得出值 i 出现的次数;然后再利用resu[i]=resu[i]+resu[i-1]求解出i在原序列中的位置。

    计数排序需要两个额外的数组作辅助,提供临时存储的resu数组,存放最终排序结果的sorted_array数组,算法描述如下:

    counting_sort(array,sorted_array)//

    1、for i = 0 to max           //max为array中的最大值

    2、  resu[i]=0;

    3、for j= 1 to length(array)

    4、  resu[array[j]]=resu[array[j]]+1       //求出包含array[i]的个数

    5、for i=min+1 to max       //min为array中的最小值

    6、  resu[i]=resu[i]+resu[i-1]     // i 在序列中的位置

    7、for j=length(array) downto 1

    8、  sorted_array[resu[array[j]]] = array[j]

     //如果arr[i]==arr[i-1]的话,显然要将arr[i-1]放到arr[i]之前

    //所以要进行resu[arr[i]]--操作

    9、  resu[array[j]] = resu[array[j]]-1 

    以序列 2 5 3 1 2 3 1 3 为例,下图是实现该算法的排序过程

     

    根据算法描述,可以写出如下程序: 

    public class my{
        public static void main(String[] args)throws InterruptedException{
            int arr[]={2,5,3,2,2,3,2,1,3,9};
            int[] sorted_array=new int[arr.length];
            int max=arr[0],i=0,min=arr[0];
            //求出最小值和最大值
            for(int val:arr){
                max=max<val?val:max;
                min=min>val?val:min;
            }
            System.out.println("min = "+min);
            int[] resu=new int[max+1];
            for(int val:arr){
                resu[val]++;
            }
            for(i=min+1;i<=max;i++){
                resu[i]=resu[i]+resu[i-1];
            }
            for(i=arr.length-1;i>=0;i--){            
                sorted_array[resu[arr[i]]-1]=arr[i];
                //如果arr[i]==arr[i-1]的话,显然要将arr[i-1]放到arr[i]之前
                //所以要进行resu[arr[i]]--操作
                resu[arr[i]]--;
            }
            System.out.println();
            printArray(arr);
            printArray(sorted_array);
        }    
        static void printArray(int[] array){
            for(int val:array){
                System.out.print(val+" ");
            }
            System.out.println();
        }
    }

    可以看出,计数排序的时间复杂度是O(n),但空间复杂度是O(n),而且如果序列中的最大值如果远远大于序列长度的话,这种排序是很不划算的,因为空间浪费太大,但是对于给定范围0到k之间的数进行排序的话,效率还是挺高的,尤其是n非常大的情况下。

  • 相关阅读:
    值类型和引用类型
    Visual Staudio 2015 打开指定文件,定位到指定文件目录下
    c# datarow[] 转换成 datatable, List<T> 转datatable
    存储过程存储过程需要用两个'',先where再Group,再Order by
    SQL之case when then用法
    select 1 from table 语句中的1代表什么意思
    SqlServer使用表值函数汇总
    SQLServer2008或SQLServer2008 R2没有智能提示解决方法
    Linux下./configure && make && make install 编译安装和卸载
    Linux下web服务的搭建
  • 原文地址:https://www.cnblogs.com/codeMedita/p/7420478.html
Copyright © 2020-2023  润新知