前端三大经典排序算法

179 阅读2分钟

三大经典排序算法

  • 冒泡排序
  • 插入排序
  • 快速排序

首先,复习一下数组的基础知识

  1. arr.push()向数组尾部插入元素,返回新数组的长度
  2. arr.unshift()向数组头部插入元素,返回新数组的长度
  3. arr.pop()从数组尾部删除元素,返回被删除的元素
  4. arr.shift()从数组头部删除元素,返回被删除的元素
  5. arr.splice(m,n)从数组下标m开始删除n个元素,返回被删除的元素组成的数组,原数组被改变
  6. arr.slice(start,end)删除数组下标start到end(不含)的元素,返回被删除的元素组成的数组,原数组不变
  7. arr.concat()实现数组拼接,返回拼接后的新数组,原数组arr不变
  8. arr.sort()实现数组排序
  • arr.sort()不传递参数的情况下,只能处理10以内的排序,即按照第一个字符进行排序
  • arr.sort()传递参数的情况下,可以实现正常大小的排序
    • 升序:arr.sort((a,b) => a-b)
    • 降序:arr.sort((a,b) => b-a)

一、冒泡排序

参考生活中的冒泡现象:大泡泡在上面,小泡泡在下面(浮力的作用)
核心思想:让数组中的当前项和后一项进行比较,如果当前项比后一项大,则两项交换位置(让大的靠后)即可。

二、插入排序

三、快速排序

核心思想:

  1. 找到中间项(一般向下取整,如:Math.floor(2.5) = 2)
  2. 把它从原来的数组中移除
  3. 获取这一项的结果即为中间项的值
  4. 准备一个左边数组,再准备一个右边数组
  5. 让拿出来的每一项和中间项继续比较,比中间项小的放左边,比中间项大的放右边
  6. 每一边继续不断重复上述操作(递归)
  7. 最后拼接:左边+中间项+右边 注意:结束递归(当arr中小于等于一项的时候则不用处理)

四、手写三大经典排序算法

<script>
let arr = [10,98,5,9,3,45,65,5,54,1] // 待排序数组

// 方法一:冒泡排序
function bubble (arr) {
  if (arr.length <= 1) {
    return arr
  }
  for (let i = 0; i < arr.length - 1; i++) { // 比较的轮数
    for (let j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j] > arr[j+1]) {
        [arr[j], arr[j+1]] = [arr[j+1], arr[j]]
      }
    }
  }
  return arr
}
console.log('冒泡排序:', bubble(arr))

// 方法二:插入排序
function insert (arr) {
  if (arr.length <= 1) {
    return arr
  }
  let newArr = []
  newArr.push(arr[0])
  for(let i = 1; i < arr.length; i++) {
    for(j=newArr.length - 1; j>=0; j--) {
      if (arr[i] > newArr[j]) {
        newArr.splice(j+1, 0, arr[i])
      }
      if (j === 0) {
        newArr.unshift(arr[i])
      }
    }
  }
  return arr
}
console.log('插入排序:', insert(arr))

// 方法三:快速排序
function quick (arr) {
  if (arr.length <= 1) {
    return arr
  }
  let middleIndex = Math.floor(arr.length / 2) // 中间数的下标
  let middle = arr.splice(middleIndex, 1)[0] // 取出中间数的值并将中间数从原数组中移除
  let left = [], right = []
  for(let i = 0; i < arr.length; i++) {
    // arr[i] < middle ? left.push(arr[i]) : right.push(arr[i])
    if (arr[i] <= middle) { // 注意这里是<=,否则相等元素会丢失
      left.push(arr[i])
    }
    if (arr[i] > middle) {
      right.push(arr[i])
    }
  }
  return quick(left).concat(middle).concat(quick(right))
}
console.log('快速排序:', quick(arr))
</script>

输出结果:
冒泡排序: (10) [1, 3, 5, 5, 9, 10, 45, 54, 65, 98]
插入排序: (10) [1, 3, 5, 5, 9, 10, 45, 54, 65, 98]
快速排序: (10) [1, 3, 5, 5, 9, 10, 45, 54, 65, 98]