/**
* 桶排序:
* 简述:
* 简单说来就是分块儿排序。假设输入数组为均匀分布,然后将数据分为n段——称之为桶,将全部数据依次放入桶中,再通过递归将桶中数字取出再细分,或者利用其他排序算法,将局部数字排序,最后将桶按照区间大小重新串起即可.
* 时间复杂度:
*
* 空间复杂度:
*
* 递归式:
*
* 优点:
* 如已知数据连续、数据集中在某一个区间,可以将该算法视为一个较为高效的算法。
* 缺点:
* 算法复杂度主要取决于step的大小(也就是桶的宽度,即区间大小),以及用于桶内排序的算法。若区间太大,桶内数据较多,则步入使用其他算法,若step过小,如1,而数据量又非常大,则非常不适合使用该算法。
* 可改进:
* 在一些特定情况下(如已知数据连续、数据集中在某一个区间),可以把内部排序的过程去除掉,把step设为1,也可以有效进行高效排序
* @author CheN
*
*/
public class BucketSort {
/**
* 正序
* @param array 数组
* @param step 步长,即每个桶的区间大小
* @return
*/
public static int[] asc( int[] array , int step ){
int min = array[0] , max = array[0];
for( int i = 1 ; i < array.length ; i++ ){
if( array[i] > max )
max = array[i];
if( array[i] < min )
min = array[i];
}
return sort (array , min , max , step );
}
/**
* 正序,只提供数组,步长为(max - min + 1) / 200;经对结果的测算,方法平均时间较快。
* @param array 数组
* @return
*/
public static int[] asc( int[] array ){
int min = array[0] , max = array[0];
for( int i = 1 ; i < array.length ; i++ ){
if( array[i] > max )
max = array[i];
if( array[i] < min )
min = array[i];
}
int step = (max - min + 1) / 200;
if( step < 1 )
step++;
return sort (array , min , max , step );
}
/**
* 桶排序
* @param array 数组
* @param min 最小数字
* @param max 最大数字
* @param step 步长,即桶内数字区间
* @return
*/
private static int[] sort( int[] array , int min , int max , int step ){
List<List<Integer>> list = new LinkedList<List<Integer>>();
// 计算桶个数
int num = (max - min + 1) / step;
if( num < 1 )
num++;
// 建桶
for( int i = min ; i <= max ; i = i + step ){
List<Integer> bucket = new LinkedList<Integer>();
list.add(bucket);
}
// 将数据放入对应桶内
for( int i = 0 ; i < array.length ; i++ ){
int index = ( array[i] - min ) / step;
list.get(index).add(array[i]);
}
// 对每个桶内部排序(可以递归桶排序)
for( int i = 0 ; i < list.size() ; i++ ){
list.set(i,insert(list.get(i)));
}
// 将排序后的桶放回数组
int k = 0;
for( int i = 0 ; i < list.size() ; i++ ){
List<Integer> temp = list.get(i);
for( int j = 0 ; j < temp.size() ; j++ ){
array[k] = (int) temp.get(j);
k++;
}
}
return array;
}
/**
* 桶内排序,该程序用的是插入排序(仅仅是因为int[]改为List比较方便而已,可以使用其他方法,甚至递归桶排序)
* @param list
* @return
*/
private static List<Integer> insert( List<Integer> list ) {
for (int i = 1; i < list.size() ; i++) {
int key = list.get(i);
int j = i - 1;
while ( j >= 0 && list.get(j) > key ) {
list.set(j+1,list.get(j));
j = j - 1;
}
list.set(j+1,key);
}
return list;
}
}
辅助代码写的有点多,核心算法就是sort()的那30行。
若有错误或不妥之处,敬请谅解并指点。