JavaScript 算法-合并排序的实例教程

123 阅读2分钟

合并排序是一种使用 "分而治之 "概念的排序算法。

给定一个数组,我们首先将其从中间分割,然后得到两个数组。

我们递归地执行这个操作,直到我们得到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 ,用我们传递给函数的两个数组ab 的值来填充,并按值排序。在数组上调用shift() ,将删除数组中的第一项,返回它,所以我们把它传给c.push() ,把它加到c 数组中。

这个算法的复杂性是O(n log(n)) ,这使得它非常有效。