javascript排序_了解通过JavaScript进行的合并排序

javascript排序

Previously, we covered some of the beginner sorting algorithms that are able to get the job done but quickly go out of hand with larger datasets. Now we get can start digging into some of the more efficient big boy algorithms, like merge sort. With this, we can move from the O(n^2) algorithms to a much more scalable O(nlogn) solution.

以前,我们介绍了一些初学者的排序算法 ,这些算法能够完成工作,但很快就无法处理更大的数据集。 现在我们可以开始研究一些更有效的大男孩算法,例如merge sort 。 这样,我们就可以从O(n^2)算法转移到更具扩展性的O(nlogn)解决方案。

先决条件 (Prerequisites)

Being able to think about time and space complexity via Big O Notation will be incredibly helpful. We’re also going to be looking at recursion-based examples, so you can brush up on that here.

通过Big O记号思考时间和空间的复杂性将非常有用。 我们还将要研究基于递归的示例,因此您可以在此处进行复习

概念 (Concept)

Similar to binary search, merge sort is a divide and conquer algorithm. The goal being to break down our problem into sub-problems and recursively continue to break those down until we have a lot of simple problems that we can easily put back together.

二进制搜索类似,合并排序是一种分而治之的算法。 我们的目标是将问题分解为子问题,然后递归地继续分解这些问题,直到我们遇到许多可以轻松归并的简单问题为止。

Merge sort is built off the idea of comparing whole arrays instead of individual items. First, we need to take the entire array and break it into many sub-arrays by continuously splitting everything in half until everything is alone in its own array. Since the amount of sub-arrays will be some multiple of the number of items in our main array, that’s what gives us the log in O(nlogn).

合并排序是基于比较整个数组而不是单个项目的想法而建立的。 首先,我们需要将整个数组分成多个子数组,方法是将所有内容连续分成两半,直到所有内容单独放在自己的数组中为止。 由于子数组的数量将是我们主数组中项目数的几倍,因此这就是我们登录O(nlogn)

From there we can start merging, since both arrays should already be sorted we can easily compare which numbers in each is smaller and put them in the right place. This is where the n in O(nlogn) comes from.

从这里我们可以开始合并,因为两个数组都应该已经排序,所以我们可以轻松比较每个数组中的哪个较小,并将它们放在正确的位置。 这就是O(nlogn) n的来源。

As you can see one half of the array is completed before the second half, and the first half of each before the next half (the different colors represent different arrays).

如您所见,数组的一半在下半部分之前完成,每个数组的前半部分在下一半之前完成(不同的颜色表示不同的数组)。

Graphic/Animation thanks to VisuAlgo.net

图形/动画得益于VisuAlgo.net

实践数据 (Practice Data)

Here’s the array of 50 unsorted items I’ll be referring to.

这是我将要参考的50个未排序项目的数组。

const unsortedArr = [31, 27, 28, 42, 13, 8, 11, 30, 17, 41, 15, 43, 1, 36, 9, 16, 20, 35, 48, 37, 7, 26, 34, 21, 22, 6, 29, 32, 49, 10, 12, 19, 24, 38, 5, 14, 44, 40, 3, 50, 46, 25, 18, 33, 47, 4, 45, 39, 23, 2];

合并 (Merge)

To simplify our problem we can start by creating a utility function that’ll merge two sorted arrays. There are many different ways of doing this but I found this the most succinct.

为了简化我们的问题,我们可以从创建一个实用程序函数开始,该函数将合并两个排序的数组。 有许多不同的方法可以做到这一点,但我发现这是最简洁的。

As long as there are items in either array, check if the first item in either array is smaller, then throw it into sorted and remove that item from the array with shift(). When that’s done, if there’s anything leftover, like when one array is larger, concatenate that onto the end.

只要任一数组中都有项,请检查任一数组中的第一项是否较小,然后将其放入已排序的数组中,并使用shift()将其从数组中删除。 完成后,如果还有任何剩余的内容(例如,一个数组较大时),则将其连接到末尾。

So both arrays are gradually shrinking until one of them is empty with the leftovers thrown onto the end, since it’s already sorted.

因此,这两个数组都在逐渐缩小,直到其中一个为空,剩下的都扔到了最后,因为它已经排序。

const merge = (arr1, arr2) => {
  let sorted = [];

  while (arr1.length && arr2.length) {
    if (arr1[0] < arr2[0]) sorted.push(arr1.shift());
    else sorted.push(arr2.shift());
  };

  return sorted.concat(arr1.slice().concat(arr2.slice()));
};

console.log(merge([2, 5, 10, 57], [9, 12, 13]));

排序 (Sorting)

This is the easy part, we can use a recursive function to continuously cut our array in half, using slice() to save the data on either side of the center. It’ll return when we have our 1 item arrays then we’ll use our merge utility to start building them back into one large array, with every merge sorting them along the way.

这是简单的部分,我们可以使用递归函数将数组连续切成两半,使用slice()将数据保存在中心的任一侧。 当我们拥有1个项目数组时,它将返回,然后我们将使用merge实用程序开始将它们重新构建为一个大数组,每次合并都会对它们进行排序。

const mergeSort = arr => {
  if (arr.length <= 1) return arr;
  let mid = Math.floor(arr.length / 2),
      left = mergeSort(arr.slice(0, mid)),
      right = mergeSort(arr.slice(mid));

  return merge(left, right); 
};

console.log(mergeSort(unsortedArr));

结论 (Conclusion)

While Merge sort is the best algorithm we’ve covered so far since it’s O(nlogn), it’s good to keep in mind that it works better with larger amounts of data. If you don’t know how much data you’ll need sorted consider using another algorithm, like insertion sort, when the dataset is small enough to get the best of both worlds.

自从O(nlogn)以来,合并排序是迄今为止我们讨论过的最好的算法,但是请记住,合并排序可以更好地处理大量数据。 如果您不知道需要多少数据,请考虑使用另一种算法,例如插入排序,此时数据集必须足够小以达到两全其美的效果。

翻译自: https://www.digitalocean.com/community/tutorials/js-understanding-merge-sort

javascript排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值