本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述
使用归并排序对一个非有序数组进行升序的排序。
示例:
输入:[5, 8, 6, 3, 4, 7, 1, 2]
输出:[1, 2, 3, 4, 5, 6, 7, 8]
二、思路分析
归并排序的思路主要就是两字:分、合。
分: 简单来说就是把数组进行二分操作,把一个完整的数组均分成两个组数,然后再不断的对分出来的子数组递归的进行分的操作,直到分成一个一个的单数数组。
合: 合就是分出来的一个一个的单数数组合两两结合,合并成有序的数组,然后在对这些有序的数组进行第二轮,第三轮的有序合并,直到把全部的子数组合并为一个完整数组。
如何合并两个有序数组: 这个说简单点就是通过循环去比较大小就可以了。
[5, 8, 6, 3, 4, 7, 1, 2]
/ \
[5, 8, 6, 3] [4, 7, 1, 2]
/ \ / \
[5, 8] [6, 3] [4, 7] [1, 2]
/ \ / \ / \ / \
[5] [8] [6] [3][4] [7] [1] [2]
\ / \ / \ / \ /
[5, 8] [3, 6] [4, 7] [1, 2]
\ / \ /
[3, 5, 6, 8] [1, 2, 4, 7]
\ /
[1, 2, 3, 4, 5, 6, 7, 8]
三、AC 代码
Array.prototype.mergeSort = function () {
const rec = (array) => {
if(array.length <= 1) return array
const res = []
const mid = Math.floor(array.length / 2)
const left = array.slice(0 , mid)
const right = array.slice(mid, array.length)
const _left = rec(left)
const _right = rec(right)
while(_left.length && _right.length) {
_left[0] < _right[0]
? res.push(_left.shift())
: res.push(_right.shift())
}
_left.length && res.push(..._left)
_right.length && res.push(..._right)
return res
}
const newArray = rec(this)
newArray.forEach( (v, i) => this[i] = v )
}
const arr = [5, 8, 6, 3, 4, 7, 2, 1]
arr.mergeSort()
console.log(arr) // [ 1, 2, 3, 4, 5, 6, 7, 8 ]
四、总结
排序在项目当中是非常常见的场景,所以排序算法是每个程序员都必须掌握并且熟练运用的算法之一。
归并排序是建立再 归并 操作上的一种有效,稳定的排序算法。
该算法是非常典型的 分治法 的应用。
先使每个子数组有序,再将两个有序子数组合并成一个有序数组,直到全部合并完成。
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情