算法篇-十大经典排序算法之桶排序
程序员文章站
2024-03-22 09:36:46
...
echo编辑整理,欢迎转载,转载请声明文章来源。欢迎添加echo微信(微信号:t2421499075) 交流学习。
什么是桶排序
首先说一下桶排序的桶是什么概念,这里的“桶”是一个区间范围,里面可以承载一个或多个元素。桶排序的第一步就是确定桶的个数和区间。具体的建立多少个桶、每个桶的区间范围是多少,有不同的方式,我们这里使用桶的数量等于原始数列的元素的数量(为什么等于数列的数量,后面会讲到)。除了最后的一个桶只包含最大值,其他的值分散在其他桶里。
桶排序也是分配排序的一种,但其是基于比较排序的,这也是与基数排序最大的区别所在。
动图演示
声明图片来源: https://www.sohu.com/a/278768401_478315
Java代码实现
public class Test {
public static void main(String[] args) {
int[] arr = {1, 3, 6, 9, 2, 5, 11, 4, 8};
print("原数组: ", arr);
bucketSort(arr);
print("排序后的数组: ", arr);
}
public static void bucketSort(int[] arr){
// 计算最大值与最小值
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int i = 0; i < arr.length; i++){
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
// 计算桶的数量
int bucketNum = (max - min) / arr.length + 1;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
for(int i = 0; i < bucketNum; i++){
bucketArr.add(new ArrayList<Integer>());
}
// 将每个元素放入桶
for(int i = 0; i < arr.length; i++){
int num = (arr[i] - min) / (arr.length);
bucketArr.get(num).add(arr[i]);
}
// 对每个桶进行排序
for(int i = 0; i < bucketArr.size(); i++){
Collections.sort(bucketArr.get(i));
}
// 将桶中的元素赋值到原序列
int index = 0;
for(int i = 0; i < bucketArr.size(); i++){
for(int j = 0; j < bucketArr.get(i).size(); j++){
arr[index++] = bucketArr.get(i).get(j);
}
}
}
private static void print(String str, int[] arr) {
for (int i = 0; i <= arr.length - 1; i++) {
if (i == 0) {
System.out.print(str + "[" + arr[i] + ", ");
} else if (i == arr.length - 1) {
System.out.print(arr[i] + "]");
} else {
System.out.print(arr[i] + ", ");
}
}
System.out.println();
}
}
核心原理
划分多个范围相同的区间,每个子区间自排序,最后合并。
算法过程如下
- 第一步:计算最大值和最小值
- 第二步:根据最计算出来最大、小值,来分配桶的个数(桶的个数以可能将数据平均分配到每个桶为准)
- 第三步:每个桶内排序
- 第四步:桶和桶之间完成合并
时间复杂度
O(N + C) 其中C=N*(logN-logM)
桶排序的优缺点
优点:实现简单,在数据量小的情况下性能良好,是稳定的排序算法
缺点:严重依赖于额外的存储空间
适用场景
适合小数据量
上一篇: 学API接口测试,致富植发(七)Sqlite3 数据库
下一篇: Git的常用操作