js中sort函数

前言

以前在学习jjavaScript时, 遇到数组的排序算法sort只是记住了使用方法。 最近在刷leetCode。 遇到了一题是:合并两个有序的数组的题。 对于该题, 我给出了两种解题方法。 一个是使用归并的思想, 该方法时间效率高, 但是编写稍微有一点点麻烦。 如果不讲究时间效率, 而是看代码的优雅度, 我也编写了一个使用sort的方法解此题。 以下便是我在使用sort方法时的一些想法。

遇到的问题

原题题目:

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

由于需要合并到nums1中, 所以需要在nums内存中修改。 这里说一个题外话——数组的哪些方法会改变原数组

  • splice
  • sort
  • reverse
  • push
  • pop
  • shift
  • unshift

我的思路就是, 直接把两个nums2合并到nums1上。 然后直接排序。 代码如下:

nums1.splice(m)
Array.prototype.splice.apply(nums1, [0,0].concat(nums2))
nums1.sort(function(a, b){return a - b})

问题一:由于需要在nums1的内存上做修改, 所以需要使用splice并用apply方法, 使用数组的方式做参数

问题二: 因为数组中包含负数。 所以如果直接使用sort方法会出现排序失败的情况。这里使用一个比较函数作为参数传入sort方法中。使其可以排序成功。 比较函数如下:function (a, b){return a -b}

对于sort方法的说明

  1. 无参数情况:直接调用sort()方法, 如果不传入比较函数, 默认会以字典排序的顺序为结果
  2. 传入比较函数的情况: 具体的返回结果与比较函数有关

那么为什么传入一个比较函数就可以实现这样的效果呢?

chrome浏览器使用v8引擎, 使用了快速排序(它属于交换排序), 大部分排序算法步骤分解之后, 最细节的操作都是两个数的相互比较。
js中sort()默认以字典排序比较方式, 如果处理字符串类型的数组吗直接使用sort方法就可以, 不需要提供参数。 数值类型的数组提供自定义排序方法的话, 有时会返回预期以外的结果, 就如有负数的情况。
如果传入函数作为参数, 函数返回值为负数时, 代表第一个比第二个小, 0 代表相等, 正数代表参数一大于参数二。 这里的大小时相对的概念, 比较函数确定小的数排在前面。(以上来自知乎)

总之就是, sort会将较小的元素排在前面, 如果约定那个元素较小?

如果没有比较函数作为参数, 那就用按照字典顺序为标准(一般来说都是ascll编码的排序)。
如果传入了比较函数, 那么元素的大小将由比较函数确定, 如何确定?
例如:function(a, b)(return a- b)。 比较函数返回正, 代表a大于b, 就会将b排在前面;如果返回为负数吗代表a小于b,会将a排在前面;所以如果我们给结果加一个负号, 就会颠倒他们

为什么传入的函数就可以控制排序?

在之前我是有比较大的疑问的, 在这里使用冒泡算法简单模拟一下sort排序。就不会有疑问了

Array.prototype.msort = function(sorter){
    var len = this.length
    var a, b, temp
    for(let i = 0; i < len; i++) {
        for(let j = i; j < len - i; j ++){
            if(this[j] < this[j - 1]){//这里就会做一个比较
                swap(this[j], this[j-1])
            }
        }
    }
}

以上代码是简单的冒泡排序。 稍加改变, 把有注释的代码改变为如下:

if(sorter(this[j], this[j - 1]) > 0){
    //交换过程
}

通过这里简单的模拟, 应该就能够明白sort方法了。

结尾

正在慢慢养成把自己学到的东西写下来的习惯。 加油!

猜你喜欢

转载自blog.csdn.net/qq_34178990/article/details/80565804