合并排序是一种使用 "分而治之 "概念的排序算法。
给定一个数组,我们首先将其从中间分割,然后得到两个数组。
我们递归地执行这个操作,直到我们得到1个元素的数组。
然后,我们开始从头开始建立排序的数组,将我们得到的各个项目排序。
假设我们的数组是这样的。
[4, 3, 1, 2]
我们首先把这个数组分成两个数组。
[4, 3]
[1, 2]
然后我们递归地划分这些数组。
[4]
[3]
和
[1]
[2]
然后是构建结果,首先对这些元素进行排序。
[3, 4]
[1, 2]
然后我们将这两个数组合并。
[1, 2, 3, 4]
让我们再做一个例子,数组里有更多的项目,这次是用字母。
['e', 'g', 'a', 'd', 'f', 'c', 'b']
我们把这个数组一分为二。
['e', 'g', 'a']
['d', 'f', 'c', 'b']
然后我们将第一个数组一分为二。
['e']
['g', 'a']
然后我们再把第二个结果除掉。
['g']
['a']
我们现在取原数组的第二部分,并将其分成2份。
['d', 'f']
['c', 'b']
我们把这两个项目都除掉。
['d']
['f']
['c']
['b']
现在我们有一个1项数组的列表。
['e']
['g']
['a']
['d']
['f']
['c']
['b']
现在我们把它们成对排序。
['e', 'g']
['a', 'd']
['d', 'f']
['c', 'b']
然后我们对前两个数组和后两个数组进行排序。
['a', 'd', 'e', 'g']
['c', 'b', 'd', 'f']
最后,我们合并我们得到的两个数组。
['a', 'b', 'c', 'd', 'e', 'f', 'g']
我们可以用两个函数来实现这个算法。第一个叫mergeSort ,这是我们要调用的函数,另一个叫_mergeArrays ,它负责合并数组的工作。我在它的名字前加上了_ ,以表示它不应该被直接调用。
它们都在这里。
const _mergeArrays = (a, b) => {
const c = []
while (a.length && b.length) {
c.push(a[0] > b[0] ? b.shift() : a.shift())
}
//if we still have values, let's add them at the end of `c`
while (a.length) {
c.push(a.shift())
}
while (b.length) {
c.push(b.shift())
}
return c
}
const mergeSort = (a) => {
if (a.length < 2) return a
const middle = Math.floor(a.length / 2)
const a_l = a.slice(0, middle)
const a_r = a.slice(middle, a.length)
const sorted_l = mergeSort(a_l)
const sorted_r = mergeSort(a_r)
return _mergeArrays(sorted_l, sorted_r)
}
请注意,在_mergeArrays() 中,我们初始化了一个结果数组c ,用我们传递给函数的两个数组a 和b 的值来填充,并按值排序。在数组上调用shift() ,将删除数组中的第一项,返回它,所以我们把它传给c.push() ,把它加到c 数组中。
这个算法的复杂性是O(n log(n)) ,这使得它非常有效。