桶排序(这个排序太强了)

桶式排序不再是一种基于比较的排序方法,它是一种比较巧妙的排序方式,但这种排序方式需要待排序的序列满足以下两个特征:

  1   待排序列所有的值处于一个可枚举的范围之类;

  2   待排序列所在的这个可枚举的范围不应该太大,否则排序开销太大。

排序的具体步骤如下:

(1)对于这个可枚举范围构建一个buckets数组,用于记录“落入”每个桶中元素的个数;

(2)将(1)中得到的buckets数组重新进行计算,按如下公式重新计算:

               buckets[i] = buckets[i] +buckets[i-1] (其中1<=i<buckets.length); 

桶式排序是一种非常优秀的排序算法,时间效率极高,它只要通过2轮遍历:

               第1轮遍历待排数据,统计每个待排数据“落入”各桶中的个数,

               第2轮遍历buckets用于重新计算buckets中元素的值,2轮遍历后就可以得到每个待排数据在有序序列中的位置,然后将各个数据项依次放入指定位置即可。

桶式排序的空间开销较大,它需要两个数组,

               第1个buckets数组用于记录“落入”各桶中元素的个数,进而保存各元素在有序序列中的位置,

               第2个数组用于缓存待排数据。

桶式排序是稳定的。

如果待排序数据的范围在0~k之间,那么它的时间复杂度是O(k+n)的

桶式排序算法速度很快,因为它的时间复杂度是O(k+n),而基于交换的排序时间上限是nlg n。

但是它的限制多,比如它只能排整形数组。而且当k较大,而数组长度n较小,即k>>n时,辅助数组C[k+1]的空间消耗较大(要求数字要分布均匀,最大值和总个数差距不要太大)。

当数组为整形,且k和n接近时, 可以用此方法排序。(有的文章也称这种排序算法为“计数排序”)

 

 

//
/**  
 * 桶式排序:  
 * 桶式排序不再是基于比较的了,它和基数排序同属于分配类的排序,  
 * 这类排序的特点是事先要知道待排 序列的一些特征。  
 * 桶式排序事先要知道待排 序列在一个范围内,而且这个范围应该不是很大的。  
 * 比如知道待排序列在[0,M)内,那么可以分配M个桶,第I个桶记录I的出现情况,  
 * 最后根据每个桶收到的位置信息把数据输出成有序的形式。  
 * 这里我们用两个临时性数组,一个用于记录位置信息,一个用于方便输出数据成有序方式,  
 * 另外我们假设数据落在0到MAX,如果所给数据不是从0开始,你可以把每个数减去最小的数。  
 */

public class bucketSort {    
     public static void bucketSort(int[] keys,int from,int len,int max)    
        {    
            int[] temp=new int[len];    
            int[] count=new int[max];  //记录每个元素出现的次数和                                   
            for(int i=0;i<len;i++)    
            {    
                count[keys[from+i]]++;//记次数的(每个元素在对应位置上出现了多少次)   这的++用来计次数的 
            } 
            for(int i=1;i<max;i++)   //从  1 开始的哦,小于的是max 
            {    
                count[i]=count[i]+count[i-1];//这意味着有多少数目小于或等于i,因此它也是position+ 1   
            }   
            System.arraycopy(keys, from, temp, 0, len);    
            for(int k=len-1;k>=0;k--)//从最末到开头保持稳定性 (从最末到开头的。)    
            {                  
                keys[--count[temp[k]]]=temp[k];// count[]中的次数减去一,给keys分配的不同的位置。。这点难理解  这里的--可以理解为
                //每个数的操作,提取出一个数,就在count的次数中减去一个。
            }    
        }              
        public static void main(String[] args) {      
            int[] a={1,4,8,3,2,9,5,0,7,6,9,10,9,13,14,15,11,12,17,16};    
            bucketSort(a,0,a.length,20);//actually is 18, but 20 will also work         
            for(int i=0;i<a.length;i++)    
            {    
                System.out.print("_"+a[i]);    
            }       
        }     
}    

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值