合并排序算法排序过程
每个程序员都需要了解他们的算法和数据结构。 在研究它们时,您需要确保确切了解它的功能,时间和空间的复杂性以及采用这种方式的原因,并且不仅能够对其进行编码,而且能够手动执行。 这就是基本算法的全部意义。
欢迎来到基本算法的第一次安装,今天在这里,我们将介绍合并排序。 合并排序是用于对大型数据集进行排序的最可靠的一致且性能最佳的排序算法之一,比起快速排序平均而言, 最糟糕的情况下执行的比较少了近40%。 因此,让我们深入研究一下此算法是什么。
合并排序算法
首先,让我们看一个简单的数字数组,这些数字是乱序的,我们要对其进行排序:
var arr = [ 27 , 369 , 63 , 126 , 252 , 990 , 54 , 18 ]
合并排序算法可以采用这些数字,并以一致且有效的方式将它们按大小从小到大或从小到大的顺序排列。 合并排序采用递归的分治方法。 也就是说,它通过调用自身将数组分解为越来越小的数组,直到每个数组中只有一个元素为止。 然后,它一次比较两个数字,将它们排序,然后将它们返回给自己,因为它从递归调用函数中退出。 因此,我们上面的数组变成了以下子数组:
[[27 , 369 , 63 , 126 ],
[ 252 , 990 , 54 , 18 ]]
并再次放入:
[[[27 , 369 ], [ 63 , 126 ]], [[ 252 , 990 ], [ 54 , 18 ]]]
最后一次:
[[[[27 ], [ 369 ]], [[ 63 ], [ 126 ]]], [[[ 252 ], [ 990 ]], [[ 54 ], [ 18 ]]]]
将元素分类到子数组中后,需要对每对元素进行求值,以便在合并在一起时,左值小于右值。 在此示例中,仅最后一对单元素数组在左侧具有较大的值,因此[54], [18]
将合并为[18,54]
:
[[[27 , 369 ], [ 63 , 126 ]], [[ 252 , 990 ], [ 18 , 54 ]]]
在最小的元素保持在最多嵌套子数组的index [0]的情况下,现在可以有效地按顺序合并子数组。 为此,比较两个数组的第一个元素。 然后,从子数组中取出较小的元素,然后将它们放入要返回的数组中,同时将它们从要比较的数组中取出。
因此,比较数组[27, 369]
和[63, 126]
,我们只需要查看数组的第一项即可。 由于27 <63,因此27将被从第一个数组中取出,并将其添加到我们将返回的数组中。 这使我们可以比较[369], [63,126]
。 我们只需要再次查看第一个元素,然后看下一个63,因此我们返回的数组为[27,63]
,我们还有[369], [126]
进行比较。 然后,我们添加126,只剩下369,因此我们将其添加。 总而言之,步骤如下所示:
[27 , 369 ] [ 63 , 126 ]
[]
[ 369 ] [ 63 , 126 ]
[ 27 ]
[ 369 ] [ 126 ]
[ 27 , 63 ]
[ 369 ]
[ 27 , 63 , 126 ]
[ 27 , 63 , 126 , 369 ]
第二次迭代后,数组如下所示:
[[27 , 63 , 126 , 369 ], [ 18 , 54 , 252 , 990 ]]
然后以完全相同的方式再次合并数组,将27与18进行比较,然后将27与54进行比较,再将63与54进行比较,依此类推,直到对整个数组进行排序并返回为止。
当我前面提到需要对每个对进行评估,并且第一步只需要交换[54],[18]
,这两个对都保存在自己的数组中。 这意味着可以创建一个函数来比较所有实例中的数字,方法是比较两个数组的索引0处的元素,然后在将较小的项添加到返回数组中时将其删除。 这将一直运行到其中一个数组为空,而另一个数组的其余元素将附加到返回元素的末尾。
数组将以这种方式递归合并在一起,直到只剩下一个数组,然后将其完全排序。 在某种程度上,您可以将其分为两个基本步骤:
- 合并两个数组:合并两个数组。 比较其中两个的第一个元素。 应该从该数组中删除较小的元素,并将其添加到我们要返回的数组末尾。 当从一个数组中删除所有元素时,只需将其他元素的其余部分添加到已排序的数组中并返回它。
- 分而治之:取一个数组。 找到它的中间。 将其左侧的所有内容传递到divid