数组的排序算法[JavaScript]

排序算法将一串数组(一个列表)中的元素(整数,数字,字符串等)按某种顺序(增大,减小,字典顺序等)重新排列。

有很多种不同的排序算法,每一种都有各自的优势和限制。

这里主要分享常见的冒泡排序、选择排序、插入排序、归并排序快速排序的简单实现。

所有的代码都可以直接复制进行测试~

冒泡排序

冒泡排序是排序算法中最简单的一个,但从运行时间的角度来说,冒泡排序是最差的一个。

冒泡排序会比较所有相邻的两个项,如果第一个比第二个大,就将它们交换。元素项向上移动至正确的顺序,像起跑升至表面。故而称之为冒泡排序。

简单实现

  <script>
    function bubbleSort(arr) {
      let len = arr.length
      // 外循环 有n个数字就比较n-1轮
      for (let i = 0; i < len-1; i++) {
        // 从内循环减去从外循环中已跑过的次数,优化不必要的比较
        for (let j = 0; j < len - 1 - i; j++) {
          if (arr[j] > arr[j + 1]) {
            // 使用ES6语法交换数组元素
            [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
          }
        }
      }
      return arr
    }

    // 测试一下结果
    let arr1 = [3, 5, 2, 6, 1]
    console.log(bubbleSort(arr1))
  </script>

选择排序

选择排序是一种原址比较排序算法。思路是找到数据结构中最小值放在第一位、再找到第二小的值放在第二位……以此类推。

简单实现

  <script>
    function selectionSort(arr) {
      // 定义所需变量
      let len = arr.length
      // 当前正在寻找的最小值索引
      let indexMin
      // 从第一位开始寻找最小值,需要找 n-1 轮
      for (let i = 0; i < len - 1; i++) {
        // 当前要找的第i小的数字
        indexMin = i
        // 将最小值位置的值与后面的值对比(所以要找到最后一个) 找出后面最小值的索引值
        for (let j = i; j < len; j++) {
          if (arr[indexMin] > arr[j]) { indexMin = j }
        }
        // 如果现在占坑(正在寻找的位置)的值不是最小的,那就与最小值交换
        if (i !== indexMin) {
          [arr[i], arr[indexMin]] = [arr[indexMin], arr[i]]
        }
      }
      return arr
    }

    // 测试一下
    let arr1 = [2, 7, 3, 1, 5]
    console.log(selectionSort(arr1))
  </script>

插入排序

插入排序就像我们平时打扑克牌排手牌一样,先假定第一张牌已经拿到手了,然后抽牌,与第一张牌进行比较——是插在第一张前面还是放在第二张的位置,以此类推构件最后的排序数组。在数组长度较小时,插入排序性能优于冒泡排序和选择排序。

简单实现

  <script>
    function insertSort(arr) {
      let len = arr.length
      // 代表需要被排序的值(抽到的牌)
      let temp
      // 从第二项开始比,所以i=1。需要比到最后一个,所以 i < len。
      for (let i = 1; i < len; i++) {
        // 存放当前的索引和值
        let j = i
        let temp = arr[i];
        // 比较当前值和前一个值 如果前一个值大就把他往后挪 直到找到位置或索引值为0
        while (j > 0 && arr[j - 1] > temp) {
          arr[j] = arr[j - 1]
          j--
        }
        // 把当前值插入应该在的地方
        arr[j] = temp
      }
      return arr
    }

    // 测试一下
    let arr1 = [4, 1, 5, 2, 6]
    console.log(insertSort(arr1))
  </script>

归并排序

归并排序是一种分而治之的算法。思想是将原始数组切分成较小的数组,直到每个小数组只有一个位置,接着将小数组排序并归并为一个大数组。用到了递归的思想。

简单实现

    <script>
      function merge(left, right) {
      console.log(left, right)
      // 存放结果的数组
      let result = []
      let il = 0
      let ir = 0
      // 迭代接收到的数组
      while (il < left.length && ir < right.length) {
        // 比较两个数组的项哪个小,将小的数组先添加到结果数组中并递增控制变量
        if (left[il] < right[ir]) {
          result.push(left[il++])
        } else {
          result.push(right[ir++])
        }
      }
      // 将剩余项添加至结果数组
      while (il < left.length) {
        result.push(left[il++])
      }
      while (ir < right.length) {
        result.push(right[ir++])
      }
      return result
    }

    function mergeSort(arr) {
      // 递归的停止条件 如果数组长度为 1,则返回这个数组
      if (arr.length == 1) return arr
      // 将数组递归拆分成小数组,并在归并过程中进行排序
      let mid = Math.floor(arr.length / 2)
      let left = mergeSort(arr.slice(0, mid))
      let right = mergeSort(arr.slice(mid, arr.length))
      return merge(left, right)
    }

    var arr1 = [3, 7, 2, 8, 1]
    console.log(mergeSort(arr1))
  </script>

快速排序

快速排序也许是最常用的算法了。和归并排序一样,快速排序也用到了分而治之的方法,同样用到了递归。

简单实现

  <script>
    // 找一个基准点 通过比较分为左右两个数组 然后递归进行比较
    function quickSort(arr) {
      if (arr.length == 0) return [];

      let cIndex = Math.floor(arr.length / 2)
      // 重要 要把c分出来
      let c = arr.splice(cIndex, 1)
      let l = []
      let r = []

      for (let i = 0; i < arr.length; i++) {
        if (arr[i] < c) {
          l.push(arr[i]);
        } else {
          r.push(arr[i])
        }
      }

      return quickSort(l).concat(c, quickSort(r))
    }

    let arr1 = [2, 5, 2, 6, 1, 7]
    console.log(quickSort(arr1));
</script>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值