let arr = [0, 17, 33, 5, 3, 54, 9, 13, 36, 11, 1, 2, 3,];
bucketSort(arr, 10);
function bucketSort(arr, maxDigit) {
let counter = [];
// 初始化桶,分了10个桶 maxDigit=10
for (let i = 0; i < maxDigit; i++) {
counter[i] = [];
}
for (let j = 0; j < arr.length; j++) {//j代表当前值的下标
//当前值放入第几个桶中,如果越界放入最后一个桶
let numbuckets = parseInt(arr[j] / 10) > 9 ? maxDigit - 1 : parseInt(arr[j] / 10);
//如果是空桶直接放进去,结束此次循环
if (!counter[numbuckets].length) {//如果是空桶
counter[numbuckets][0] = arr[j];
} else {
//第一种方法--冒泡排序对比,放入桶中
// for (let n = counter[numbuckets].length - 1; n >= 0; n--) {
// //n代表当前桶里元素的长度,一个个去对比
// let tem = arr[j];
// if (counter[numbuckets][n] > tem) {
// //tem代表取出的元素要和桶中的元素对比
// counter[numbuckets][n + 1] = counter[numbuckets][n];
// counter[numbuckets][n] = tem;
// } else {
// counter[numbuckets][n + 1] = tem;
// }
// }
//第二种方法--插入排序对比放入桶中
let len = counter[numbuckets].length - 1;
// arr[j] 是抽到的牌和桶里的牌做比较
let tem = arr[j];
while (len >= 0 && arr[j] < counter[numbuckets][len]) {
counter[numbuckets][len + 1] = counter[numbuckets][len];
len--;
}
//这里有一个不好理解的点,
//如果手里的牌大于桶里的牌,直接把牌放入最后一个(也就是长度+1)
// 如果手里的牌小于桶里的某一个牌,
// 但又不是小于桶里所有的牌,也把牌放入当前下标+1
// 如果手里的牌小于桶里所有的牌,下标越界了,也把牌放入当前下标+1
//3种情况必须都考虑到,否则有bug
//这里是把3种代码的情况都包含进来了,所以可以简写为一次即可
counter[numbuckets][len + 1] = tem;
}
}
//这里每个桶就排好序了,开始合并桶了
let allLen = arr.length - 1;//从后向前放
//依次取出桶中的元素,按顺序放入原数组完成排序
for (let i = counter.length - 1; i >= 0; i--) {
let numbucket = counter[i].length - 1;
while (numbucket >= 0) {
arr[allLen--] = counter[i][numbucket];
numbucket--;
}
}
return arr;
}
桶排序
最新推荐文章于 2023-05-10 21:37:04 发布