排序算法(js版)

常见的有冒泡排序、插入排序、选择排序、快速排序

1-冒泡排序

冒泡排序就是不断遍历待排序序列,不断比较相邻的元素,顺序不对就交换顺序,将最大的值不断冒泡到末尾,
我们可以将数组分为两个区域,一个区域是已经有序的部分,另一个区域是未排序的部分。
在冒泡排序中,每一轮遍历都会将数组的最大元素“冒泡”到末尾,因此,经过每一轮遍历后,都会将当前未排序区域的最大元素放到已排序区域的末尾。
对于第 i 轮遍历,已经有前 i 个元素已经处于有序状态,因此未排序区域的长度为 n-i。

//时间复杂度n^2
  function bubblesort(arr) {
    let len = arr.length
    for (let i = 0; i < len - 1; i++) {
      for (let j = 0; j < len - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
          let temp = arr[j]
          arr[j] = arr[j + 1]
          arr[j + 1] = temp
        }
      }
    }
    return arr
  }

进行优化,时间复杂度不变
加入标志位,如果当前遍历没有发生元素交换,说明已经有序,
记录交换元素的最后位置,将这个位置之后元素视为有序,只需要遍历最后位置之前的元素即可

function bubblesort(arr) {
    let len = arr.length, flag = true, lastindex = len - 1
    for (let i = 0; i < len - 1 && flag; i++) {
      let exchangeIndex = 0
      flag = false
      for (let j = 0; j < lastindex; j++) {
        if (arr[j] > arr[j + 1]) {
          [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]
          flag = true
          // console.log(j + 1)
          exchangeIndex = j
        }
      }
      lastindex = exchangeIndex
      // console.log("last", lastindex)
    }
    return arr
  }
}
2-选择排序

选择排序是从未排序序列中选择最大或者最小的元素,加入到已排序序列的起始位置

 //时间复杂度是n^2,
  function selectSort(arr) {
    let len = arr.length
    //外层循环遍历数组
    for (let i = 0; i < len; i++) {
      //记录最小数的下标
      let minIndex = i
      //内层循环找到最小数
      for (let j = i; j < len; j++) {
        if (arr[j] < arr[minIndex])
          minIndex = j
      }
      //最小数
      //将最小数和当前交换,i之前就是已排序序列
      if (minIndex != i) {
        let temp = arr[i]
        arr[i] = arr[minIndex]
        arr[minIndex] = temp
      }
    }
    return arr
  }
  console.log(selectSort([1, 4, 2, 3, 8, 5, 6]))
3-插入排序

从未排序序列中取出一个元素,在已排序序列中找到应该插入的位置,保证已排序序列仍然有序,

function insertSort(arr) {
    //时间复杂度2^n
    let len = arr.length
    for (let i = 1; i < len; i++) {
      //当前处理元素
      let corrent = arr[i]
      //i之前为已排序序列
      let j = i - 1
      while (j >= 0 && corrent < arr[j]) {
        arr[j + 1] = arr[j]
        j--;
      }//考虑极端,跳出循环的时候j=-1,找到合适的地方插入
      arr[j + 1] = corrent
    }
    return arr
  }
  console.log(insertSort([1, 4, 2, 3, 8, 5, 6]))
 

折半插入排序

function binInsertSort(arr) {
    let len = arr.length
    if (len <= 1) return arr
    for (let i = 1; i < len; i++) {
      //当前遍历元素
      let key = arr[i]
      let left = 0, right = i - 1

      while (left <= right) {
        let mid = Math.floor((left + right) / 2)

        if (key > arr[mid]) {

          left = mid + 1
        } else {
          console.log("ok")
          right = mid - 1
        }
      }
      console.log("left", left, "right", right)
      //跳出循环的时候left就是查找到的值吗?left>right或者arr[mid]==key,left=mid-1
      for (let j = i - 1; j >= left; j--) {
        arr[j + 1] = arr[j]
      }
      arr[left] = key
    }
    return arr
  }
4-快速排序

主要针对数据量大的数据,基于分治思想,选择基准值,将比基准值小的分到左边,大的分到右边,然后对左右两个序列分别进行递归应用这个算法。

function quickSort(arr) {
    //时间复杂度nlogn
    let len = arr.length
    //递归一定定义出口
    if (len <= 1) return arr
    //选择基准值
    let mid = Math.floor(len / 2), midValue = arr[mid]
    //使用递归实现快速排序
    let left = [], right = []
    for (let i = 0; i < len; i++) {
      if (i !== mid)
        arr[i] < midValue ? left.push(arr[i]) : right.push(arr[i])
    }
    return [...quickSort(left), midValue, ...quickSort(right)]
  }
  console.log(quickSort([1, 4, 2, 3, 8, 5, 6]))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值