学习JavaScript中的合并排序

175 阅读4分钟

合并排序将完整的列表分为子列表或 "n "个子列表,并递归地继续这个过程,直到每个子列表有一个元素。一旦这个 "分而治之 "的过程完成,它就开始合并每个子列表以创建一个排序的列表。

合并排序如何工作

现在我们将借助一个例子来了解合并排序的工作。

让我们考虑另一个合并排序的例子,我们在一个数组中共有7个(奇数)元素,我们将按照升序对它们排序。

[5, 7, 1, 4, 6, 3, 2]

将该数组分为两个子数组

[5, 7, 1] and [4, 6, 3, 2]

同样,每个数组将被划分为两个子数组

[5], [7, 1] and [4, 6], [3, 2]

在这里,四个子数组中,有一个子数组只有一个元素,但其他三个数组仍然有一个以上的元素,所以我们将进一步把这些数组分别分成两个数组。

[5], [7], [1], [4], [6], [3], [2]

现在第一步已经完成,因为每个数组中只有一个项目。现在我们将比较数组元素,将这些单项数组合并成对。

[5, 7], [1, 4], [3, 6], [2]

我们对前两个数组的元素和后两个数组的元素进行比较,把小的数值移到左边,大的数值移到右边。

将对前两个数组的元素和后两个数组的元素进行比较。例如,前两个数组是[5,7]和[1,4]。首先,5将与1进行比较,然后与4进行比较。之后,第二个元素7将经历同样的过程,结果数组将是[1,4,5,7]。现在我们将处理最后两个数组,即[3,6]和[2]。经过比较,我们得到的数组将是[2,3,6]。

 [1, 4, 5, 7] [2, 3, 6]

现在我们有两个数组;[1,4,5,7]和[2,3,6]。让我们把它们分别称为**arrayA [1,4,5,7]arrayB [2,3,**6]。

首先,数组A的第一个元素 "1"将与数组B的第二个元素 "2"进行比较,较小的数字 "1"将被存储在新的排序数组中

[1]

在下一次迭代中,"2"将与数组A的下一个元素 "4"进行比较。较小的那个 "2"将被存储在新的排序数组中。

[1,2]

这一次,数组A的 "4 "将与数组B的下一个元素 "3 "相比较。因为 "3 "比较小,所以它将被插入到新的排序数组中。

[1,2,3]

这个过程将在两个数组的每个元素上进行,一旦所有元素被比较,结果数组将是;[1,2,3,4,5,6,7]。

[1, 2, 3, 4, 5, 6, 7]

JavaScript中的合并排序

我们已经了解了合并排序的工作原理,现在我们将用JavaScript编写代码。

创建一个递归函数来分割未排序的数组,我们把它命名为 "merge_sort"。递归函数总是有一个基例来停止程序。我们将未排序的数组传递给 "merge_sort"函数,在这个函数中,我们通过将数组的长度除以2来找到数组的中间索引。 此外,我们利用 "splice() "方法将数组分成子数组。

function merge_sort(unsortedArray) {
    const midle_index = unsortedArray.length / 2
    if(unsortedArray.length < 2){
      return unsortedArray
    }
    const leftArray = unsortedArray.splice(0, midle_index)
    return mergeArray(merge_sort(leftArray),merge_sort(unsortedArray))
  }

现在,我们将讨论合并两个分割数组的代码。这些拆分的数组已经在 "merge_sort "函数中进行了排序,现在我们要在 "mergeArrays"函数中合并它们。

function mergeArrays(leftArray, rightArray) {
    let ary = []
    while (leftArray.length && rightArray.length) {
        if (leftArray[0] < rightArray[0]) {
            ary.push(leftArray.shift())  
        } else {
            ary.push(rightArray.shift())
        }
    }
    return [ ...ary, ...leftArray, ...rightArray ]
}

在上面给出的函数中,"leftArray "和 "rightArray "是两个排序的数组,我们将它们合并以获得一个单一的排序数组。本例中使用了两个方法:"push()"方法在排序数组的末尾添加值,"shift()"方法删除从子数组中选择的值。最后,console.log()方法被用来测试输出。

完整的代码片断是这样的:

function mergeArrays(leftArray, rightArray) {
    let ary = []
    while (leftArray.length && rightArray.length) {
        if (leftArray[0] < rightArray[0]) {
            ary.push(leftArray.shift())  
        } else {
            ary.push(rightArray.shift())
        }
    }
    return [ ...ary, ...leftArray, ...rightArray ]
}
function merge_sort(unsortedArray) {
    const midle_index = unsortedArray.length / 2
    if(unsortedArray.length < 2){
      return unsortedArray
    }
   
    const leftArray = unsortedArray.splice(0, midle_index)
    return mergeArrays(merge_sort(leftArray),merge_sort(unsortedArray))
  }
  unsortedArray = [5, 7, 1, 4, 6, 3, 2];
  console.log(merge_sort(unsortedArray));

输出

结论

合并排序将一个列表划分为子列表,它继续划分列表,直到一个子列表得到一个元素,然后它合并所有的子列表,产生一个新的排序列表。在这篇文章中,我们学习了合并排序的概念,然后考虑了一些例子,最后,我们用JavaScript实现了它们。我们还解释了splice方法、push方法和shift方法如何在JavaScript中工作。