排序问题

128 阅读2分钟

js

在日常开发中,我们经常会碰到排序的需求,js 中数组的排序一般会想到 sort 方法。那有没有自己写过排序的方法呢?今天我们来自己写几个排序方法

给定一个数组: [5, 2, 4, 6, 1, 3],请你按照升序方式对它进行排序。

  1. 插入法:

我首先想到的是维护一份新数组,然后循环给定数组的每个元素,每次循环都去对比新数组中的元素,找到符合条件的位置,然后插入该位置。

function INSERTION_SORT(nums) {
  const res = [nums[0]]
  for (let i = 1, len = nums.length; i < len; i++) {
    const temp = res[i - 1]
    if (nums[i] < temp) {
      const index = res.findIndex(num => nums[i] <= num)
      res.splice(index, 0, nums[i])
    } else {
      res.push(nums[i])
    }
  }
  return res
}

INSERTION_SORT([5, 2, 4, 6, 1, 3]) // [1, 2, 3, 4, 5, 6]

上面的解法用到了 findIndex 和 splice,那我在想能不能不用数组已有的方法去解这道题呢?

其实利用数组的位置可以很好地解出这道题目。

循环遍历给定数组的每个元素,维护一个当前位置的变量,用该变量去对比给定数组当前位置左边的每个元素,如果该变量小于左边一个元素,那么左边一个元素往右边移动一个位置,以此类推,直到该变量大于或等于左边的元素。最后在适当的位置插入该变量。

function INSERTION_SORT(nums) {
  for (let i = 1, len = nums.length; i < len; i++) {
    const temp = nums[i]
    let j = i - 1
    while (j > -1 && temp < nums[j]) {
      nums[j + 1] = nums[j]
      j -= 1
    }
    nums[j + 1] = temp
  }
  return nums
}

INSERTION_SORT([5, 2, 4, 6, 1, 3]) // [1, 2, 3, 4, 5, 6]
  1. 分治法

递归思想:

  • 分解原问题为诺干子问题,这些子问题是原问题的规模较小的实例

  • 解决这些子问题, 递归地求解各种子问题。然后,若子问题的规模足够小,则直接求解。

  • 合并这些子问题的解为原问题的解

function MERGE_SORT(nums) {
  if (nums.length <= 1) return nums
  const midIndex = Math.floor(nums.length / 2)
  const mid = nums.splice(midIndex, 1)
  const left = []
  const right = []
  for (let i = 0, len = nums.length; i < len; i++) {
    if (nums[i] < mid) {
      left.push(nums[i])
    } else {
      right.push(nums[i])
    }
  }
  return MERGE_SORT(left).concat(mid, MERGE_SORT(right))
}

MERGE_SORT([5, 2, 4, 6, 1, 3]) // [1, 2, 3, 4, 5, 6]
  1. 冒泡法

循环给定数组长度次,每次循环都从左往右取数组元素去对比该元素右边的元素,如果比右边元素大则交换两个元素的位置,否则继续下一元素去对比该元素右侧元素。(解释的比较绕口,不知道该如何组织语言)

function BUBBLE_SORT(nums) {
  for (let i = 0; i < nums.length - 1; i++) {
    for (let j = 0; j <BUBBLE_SORT nums.length - i - 1; j++) {
      if (nums[j] > nums[j + 1]) {
        const temp = nums[j]
        nums[j] = nums[j + 1]
        nums[j + 1] = temp
      } else {
        continue
      }
    }
  }
  return nums
}

BUBBLE_SORT([5, 2, 4, 6, 1, 3]) // [1, 2, 3, 4, 5, 6]

出个思考题:给定一个数组: [5, 2, 4, 6, 1, 3],请你分别使用插入法、分治法和冒泡法以降序方式对它进行排序。