排序(五)——关于桶式排序

本文详细介绍了一种简单的桶排序算法实现方法,并通过示例代码展示了如何对一组正整数进行排序。此外,还讨论了如何通过引入最小值和最大值参数来优化算法,以支持负数排序和特定区间内的数值排序。
假设现在有一组小于M的正整数 a1、 a2 ,…… ,an ,对它们排序可以采用以下的思路:使用一个大小为M的数组buckets,这个数组的每一个单元称为一个个的bucket,桶,初始化全部为0。扫描数组a,当扫描到ai的时候,buckets[ai] 加1。这样当a扫描完之后,扫描buckets,打印非零单元的下标,它的值是几就打印几次。打印出来的值实际上就是排好序之后的数组a了。我们可以依次把它们赋值给a,使得a有序。

        代码如下:

  1.       public void bucketSort(int[] a,int max){ 
  2.  
  3. //注意了,这里 max > a[i],即 max 大于a中最大值 
  4. int[] buckets=new int[max]; 
  5. for(int i=0;i<a.length;i++) 
  6. buckets[a[i]]++; 
  7. int j=0
  8.       
  9. for(int i=0;i<buckets.length;i++) 
  10.    for(int k=1;k<=buckets[i];k++) 
  11.      a[j++]=i;            
         public void bucketSort(int[] a,int max){
		
		 //注意了,这里 max > a[i],即 max 大于a中最大值
		 int[] buckets=new int[max];
		 for(int i=0;i<a.length;i++)
			 buckets[a[i]]++;
		 int j=0;
		 	 
		 for(int i=0;i<buckets.length;i++)
			   for(int k=1;k<=buckets[i];k++)
				 a[j++]=i;			 
	}

        当然,上面的思路应该还称不上桶式排序法。都说桶排是稳定的排序法,显然上面的最后一步的做法毫无稳定性可言。为了保证稳定性,做了修改如下:

  1.               public void bucketSort(int[] a,int max){ 
  2.  
  3. //注意了,这里 max > a[i],即 max 大于a中最大值 
  4. int[] buckets=new int[max]; 
  5. for(int i=0;i<a.length;i++) 
  6. buckets[a[i]]++; 
  7.  
  8. / 计算“落入”各桶内的元素在有序序列中的位置    
  9. for (int i = 1; i < max; i++) {    
  10.   buckets[i] = buckets[i] + buckets[i - 1];    
  11. }   
  12.  
  13. // 将a的元素完全复制到tmp数组中    
  14. int tmp[] = Arrays.copyOf(a, a.length); 
  15.  
  16. // 根据buckets数组中的位置信息将待排序列的各元素放入相应位置    
  17. for (int k = a.length - 1; k >= 0; k--) {    
  18.   a[--buckets[tmp[k]]] = tmp[k]; 
  19. }             
                 public void bucketSort(int[] a,int max){
		
		 //注意了,这里 max > a[i],即 max 大于a中最大值
		 int[] buckets=new int[max];
		 for(int i=0;i<a.length;i++)
			 buckets[a[i]]++;
		 
		// 计算“落入”各桶内的元素在有序序列中的位置   
		 for (int i = 1; i < max; i++) {   
		   buckets[i] = buckets[i] + buckets[i - 1];   
		 }  

		 // 将a的元素完全复制到tmp数组中   
		 int tmp[] = Arrays.copyOf(a, a.length);

		 // 根据buckets数组中的位置信息将待排序列的各元素放入相应位置   
		 for (int k = a.length - 1; k >= 0; k--) {   
		   a[--buckets[tmp[k]]] = tmp[k];
		 }			 
	}

        搜到了这篇文章:http://blog.csdn.net/apei830/article/details/6596057
        他的参数有 min 和 max ,我在论坛上问了一下,有人说好处有两个:1、支持负数; 2、高位区间:比如 9000 ~ 10000; 的确是这样。那我就把他的代码拷过来吧,以备后用。这应该算是最优秀的代码了吧?

  1. public static void bucketSort(int[] data, int min, int max) { 
  2.     // 缓存数组 
  3.     int[] tmp = new int[data.length]; 
  4.     // buckets用于记录待排序元素的信息 
  5.     // buckets数组定义了max-min个桶 
  6.     int[] buckets = new int[max - min]; 
  7.     // 计算每个元素在序列出现的次数 
  8.     for (int i = 0; i < data.length; i++) { 
  9.         buckets[data[i] - min]++; 
  10.     } 
  11.     // 计算“落入”各桶内的元素在有序序列中的位置 
  12.     for (int i = 1; i < max - min; i++) { 
  13.         buckets[i] = buckets[i] + buckets[i - 1]; 
  14.     } 
  15.     // 将data中的元素完全复制到tmp数组中 
  16.     System.arraycopy(data, 0, tmp, 0, data.length); 
  17.     // 根据buckets数组中的信息将待排序列的各元素放入相应位置 
  18.     for (int k = data.length - 1; k >= 0; k--) { 
  19.         data[--buckets[tmp[k] - min]] = tmp[k]; 
  20.     } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值