• 欢迎光临~

手写排序算法

开发技术 开发技术 2022-10-27 次浏览

冒泡排序

/*
每次将相邻的两个进行比较,选出大的那个,一轮结束后就得到了数组中最大的元素
第二轮也是如此,重复次数-1,第二大的那个元素
说明:
比如有5个元素,我们只需要4趟就可以排好序,最后一个就是最小的 
也就是第一个for的趟数,就是循环的次数,我们只用循环arr.length-1次就可以了
当然了,遍历arr.length次也是可以的

第二个for循环控制的是每一趟的轮数
比如
第一轮的时候有5个元素,那我们就会从第一个元素开始与其它四个元素作比较,也就是会询问4次,选出最大的一个元素
第二轮的时候
*/
const bubblingSort = (arr) => {
  // 第一个for控制趟数,第二个for控制每一趟的次数
  for (let i = 1; i < arr.length; i++) {
    for (let j = 0; j < arr.length - i; j++) {
      if (arr[j] >= arr[j + 1]) {
        let temp = arr[j]
        arr[j] = arr[j + 1]
        arr[j + 1] = temp
      }
    }
  }
  return arr
}

选择排序

// 使用一个最小索引变量记住每一趟遍历比较中的最小值所处索引
// 优点:不用开辟额外的内存,复杂度一直都是O(n^2)
// 双重循环
// 我们可以理解为双指针,第一个指向每一趟的最小索引,第二个指针为前进指针
// 我们可以理解为动静指针

const selectSort = (arr) => {
  for (let i = 0; i < arr.length; i++) {
    // 初始化静指针默认指向第一个
    let minIndex = i
    // 动指针从索引为1处开始比较
    for (let j = i + 1; j < arr.length; j++) {
      // 如果动指针指向的内容比静指针小,那么就交换两个元素的位置
      if (arr[j] < arr[minIndex]) {
        minIndex = j
      }
    }
    ;[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]
  }
  return arr
}

插入排序

// 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入
// 同样的可以使用两个指针,第一个指针指向已排序数组的最后一项,第二个指针指向未排序数组的第一项
// 也就是未排序指针的前一个是已排序指针
// 之后第一个指针从后向前移动,找到合适的位置插入
// 比如已排序 2356 未排序 4,第一个指针就会从后先前依次递减找到比4小的元素插入
const insertSort = (arr) => {
  if (!Array.isArray(arr) || arr.length < 2) return arr
  // 已排序指针默认指向第一个

  // 未排序的指针可以从索引为1处开始
  for (let unsort = 1; unsort < arr.length; unsort++) {
    let curValue = arr[unsort]
    let sorted = unsort - 1
    // 当符合条件时,也就是sorted指针存在并且 已排序指针指向的元素大于未排序指针指向的元素
    while (sorted >= 0 && curValue < arr[sorted]) {
      console.log(
        `sorted 是${sorted},arr[sorted]是${
          arr[sorted]
        },unsort是${unsort},arr[unsort]是${arr[unsort]},arr是${arr.toString()}`
      )
      arr[sorted + 1] = arr[sorted]
      sorted--
    }
    arr[sorted + 1] = curValue
  }
  return arr
}

快速排序

// 选一个参考值,比它大的放在它右边的数组,比它小的放在左边的数组
// 之后对左边和右边的数组执行同样的操作

function quickSort(arr) {
  if (arr.length <= 1) return arr
  // splice返回的是一个数组
  let midValue = arr.splice(Math.floor(arr.length / 2), 1)[0]
  let left = [],
    right = []
  arr.forEach((item) => {
    if (item <= midValue) {
      left.push(item)
    } else {
      right.push(item)
    }
  })
  return quickSort(left).concat(midValue, quickSort(right))
}

持续更新……

程序员灯塔
转载请注明原文链接:手写排序算法
喜欢 (0)