我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战
桶排序
桶排序顾名思义就是若干个桶,根据自定义的映射函数将元素放入桶中,保证每个桶里的元素分配均匀。分配完毕之后将桶里的元素进行排序,最后桶里的元素的依次输出到数组里,桶排序就结束了。
桶中元素如果分配不均匀,集中在一个桶里则桶排序失效。
步骤
- 算出桶的个数
(最大值-最小值)/ 数组长度 + 1
取整 - 按照个数初始化数组
- 按照映射关系
(元素的值- 最小值 ) / 数组长度
给每个桶添加元素 - 每个桶内进行排序(任意的排序方法都行)
- 排序完毕后将桶里的元素 依次添加到数组里
代码示例
function bucketSort(arr){
let min = Math.min(...arr)
let max = Math.max(...arr)
//1. 算出桶的个数
const bucketNum = Math.floor((max-min) / arr.length )+ 1
//2. 初始化桶
const bucketArr= new Array(bucketNum)
for(let i = 0; i< bucketNum;i++){
bucketArr[i] = new Array()
}
//3. 给每个桶添加元素
for(let i = 0; i < arr.length; i++){
const num = Math.floor ((arr[i] - min) / arr.length) //相当于一个映射函数 根据这个规则将元素放进桶里
bucketArr[num].push(arr[i])
}
//4. 每个桶进行排序
let index = 0
// 桶排序的稳定性建立在每个桶内用的什么排序算法
bucketArr.map(bucket => bucket.sort()).forEach(bucket => {
for(let i = 0; i< bucket.length; i++){
arr[index++] = bucket[i]
}
})
//5. 将桶里的元素 依次添加到数组里
console.log(arr);
}
bucketSort([18,11,28,45,23,50])
归并排序
将数组从中间拆分左右两个数组,左右两个数组继续做拆分,直到数组中剩下一个元素。此时两两合并,按照小的优先合并原则。
步骤
- 首先从数组中间分割, 然后将分割好的数组再次在中间分割,直到数组长度为1
- 将分割的数组依次进行队首比较 小的放入res数组里
- 最终res数组就是从小到大的顺序排列了
代码示例
function mergeSort(arr){
const n = arr.length
if(n < 2)return arr
const mid = n >> 1 // 首先从数组中间分割
return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)))
}
function merge(left , right){
const res = []
// 将分割的数组进行队首比较 小的放入res数组里
while(left.length && right.length){
if(left[0] <= right[0]){
res.push(left.shift())
}else{
res.push(right.shift())
}
}
// left right 分别对剩余元素的存储
while(left.length) res.push(left.shift())
while(right.length)res.push(right.shift())
return res
}
console.log(mergeSort([5,4,3,2,1]));