简单排序算法实现——桶排序

桶排序 (Bucket Sort) 又称箱排序,是鸽巢排序的一种归纳结果(有关鸽巢排序的内容留待后补)。

桶排序是比较特殊的排序,它不属于比较排序,即有序的建立不是基于元素的比较与交换而消除逆序得到的,比较形象的讲,其对有序的建立是基于桶数组在物理内存上本身的连续性和有序性,将其作为索引,然后建立该索引与待排序数组的映射关系,然后通过遍历索引而倾倒出待排序元素,则倾倒的过程自然遵循桶数组的物理内存连续性而得到有序的结果。基于这一分析,桶排序不受到 O(nlogn) 的下限影响。

其工作的过程是先建立有限个数量的桶,每个桶内可以使用别的排序。然后将元素投入对应的桶中,对每个子桶进行排序。完成以后依次将子桶中的元素倒出到原始数组,得到结果。

比较特殊的情况是建立的桶的数量与待排序数组中的最大元素减去最小元素再加一的个数相同,这样的话可以实现一对一的映射,也免去了对子桶的排序。举例来说,如果原数组中有元素3,则 Bucket[3]++; 这样还有一个附加的好处是,重复的元素只要对应的桶再加一即可,在倾倒的时候,只要桶不为空则继续倾倒,也很好实现。下面的java代码给出的正是这种桶排序的实现。


java代码实现 (该实现中默认已知输入的最小值是0,实际上这是不太恰当的,比较好的做法是对最大最小值都寻找,然后分配桶空间):

//This algorithm is limited and impractical because there exists a pre-assumption
//for the input. In this case the minimum input cannot be negative and the maximum
//input should be reachable.
public class BucketSort{
	public static void BucketSort(Integer[] a){
//Find the max
		int max=a[0];				
		for(int i=0;i<a.length;i++)
			if(a[i]>max) max=a[i];
		
//		System.out.println("max="+max);
//Fill the bucket;		
		int[] Bucket=new int[max+1];
		for(int i=0;i<a.length;i++){
			Bucket[a[i]]++;
		}
		
/*		System.out.println("Bucket status:");
		for(int i=0;i<Bucket.length;i++) System.out.print(Bucket[i]+" ");
		System.out.println();
*/	
//Dump back into the array from the bucket;
		int j=0;
		for(int i=0;i<=max;i++){
			while(Bucket[i]!=0){
				a[j]=i;
				Bucket[i]--;
				j++;
			}
		}
	}
	
	public static void main(String[] args){
		System.out.println("Bucket Sort:");
		
		Integer[] elements={3,4,1,8,10,2,0,6,5};
		
		System.out.print("Original elements: ");
		for(int i=0;i<elements.length;i++) System.out.print(elements[i]+" ");
		System.out.println();
		
		BucketSort(elements);
		
		System.out.print("After sorting: ");
		for(int i=0;i<elements.length;i++) System.out.print(elements[i]+" ");
		System.out.println();
	}
}


还应该说明的是,桶排序的另一个特殊性在于对于输入数据做了预先的假设,因此也有别于一般的排序算法对任意输入数据的普适性。该假设在于:所有输入数据分布比较均匀且集中,没有出现极端的数据。在满足该条件的情况下,桶排序非常高效适用,且易于编程,可以将百万级的数据量在毫秒级的时间范围内处理完。 但是一旦该数据分布均匀集中的假设不满足,其空间效率将极低。举例来说,如果待排序数据为:-10000, 0 , 2 ,1 , 3, 20000. 在这种情况下,将创建几万个桶空间而并不使用,这显然是不合适的。


平均时间复杂度:O(n+k).


附图一张,图中的情况是每个桶是作为一个数据范围的索引,与代码实现的不太一样:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值