【4.29】补课 手写js六大排序

本文介绍了四种基本排序算法:直接插入排序、冒泡排序、选择排序和快速排序。直接插入排序通过不断让位找到合适位置插入;冒泡排序每次将最大值放到右边;选择排序每次都更新最小值下标;快速排序采用分治策略,通过一趟排序将待排记录分隔成独立的两部分。这些排序算法各有特点,适用于不同的场景。
摘要由CSDN通过智能技术生成

补课

4.29

  • 直接插入排序
function insert (arr) {
  for (let i = 1; i < arr.length; i++) {
    let current = arr[i] // 提前保存
    let j = i - 1 // 之前的序列前部排序好了 假设插入了一个新元素
    while (current < arr[j]) {
      arr[j + 1] = arr[j] // 不断让位
      j--
    }
    arr[j + 1] = current // 找到合适的位置插入
  }
  return arr
}
  • 冒泡排序
function bub (arr) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr.length - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
      }
    } // 每次都把当前最大值放在右边,再接着排剩下的
  }
  return arr
}
  • 选择排序
const selectSort = (arr) => {
  for (let i = 0; i < arr.length; i++) {
    let minindex = i
    for (let j = i; j < arr.length; j++) {
      if (arr[j] < arr[minindex]) {
        minindex = j // 每次都不断改变min下标
      }
    }
    [arr[i], arr[minindex]] = [arr[minindex], arr[i]]
    // 直接把arr[minindex]放在左边,再接着排剩下的
  }
  return arr
}
  • 快速排序
function quick (arr) {
  if (arr.length < 2) {
    return arr // 递归终止条件
  }
  let pivot = arr[0] // 哨兵
  let left = [] // 小于arr[0]
  let right = [] // 大于等于arr[0]
  for (let i = 1; i < arr.length; i++) {
    arr[i] >= pivot ? right.push(arr[i]) : left.push(arr[i])
  }
  return [...quick(left), pivot, ...quick(right)] // 递归
}
  • 归并排序
function mergeso (arr) {
  if (arr.length < 2) {
    return arr // 递归终止条件
  }
  let mid = Math.floor(arr.length / 2) // 将数组一分为二,注意js里面整数相除可以得到小数
  let left = arr.slice(0, mid)
  let right = arr.slice(mid)
  function merge (left, right) {
    let result = []
    while (left.length > 0 && right.length > 0) {
      result.push(left[0] <= right[0] ? left.shift() : right.shift()) // shift()用的可以 之前没想过
    }
    return result.concat(left, right)
  }
  return merge(mergeso(left), mergeso(right)) // 递归
  // 想象成把mergeso结束后的数组进行merge合并 2-4-8-16.....
}
  • 堆排序
//建大顶堆的其中一次排序操作 大顶堆每个节点的值大于或等于其左右孩子节点的值
function heapify (arr, i, end) {
  let current = i
  let left = 2 * i + 1
  let right = 2 * i + 2
  if (left < end && arr[current] < arr[left]) {
    current = left
  }
  if (right < end && arr[current] < arr[right]) {
    current = right
  }
  if (current != i) {
    [arr[current], arr[i]] = [arr[i], arr[current]]
    heapify(arr, current, end)
  }
}

function heapSort (arr) {
  //start标记序号最大的有孩子的节点
  let start = Math.floor(arr.length / 2) - 1
  //先建一遍大顶堆
  for (let i = start; i >= 0; i--) {
    heapify(arr, i, arr.length)
  }
  //开始排序 这时候arr[0]就是最大的数,和arr[i]直接交换,然后重建大顶堆
  for (let i = arr.length - 1; i > 0; i--) {
    [arr[0], arr[i]] = [arr[i], arr[0]]
    heapify(arr, 0, i)
  }
  return arr
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值