JavaScript中常见的排序算法(冒泡、选择、插入、快速)

一、排序算法类别

常见比较排序:

  • 冒泡排序
  • 选择排序(普通选择排序、堆排序)
  • 插入排序(普通插入排序、希尔排序)
  • 快速排序
  • 归并排序

常见非比较排序:

  • 计数排序
  • 基数排序
  • 桶排序

复杂度表:
在这里插入图片描述

二、冒泡排序 Bubble Sort(O(n²))

大致流程:
1.从第一个元素开始,比较每两个相邻元素,如果前者大,就交换位置
2.每次遍历结束,能够找到该次遍历过的元素中的最大值
3.如果还有没排序过的元素,继续1

演示图:
在这里插入图片描述
代码实现:

function bubbleSort(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]) swap(arr, j ,j+1)
    }
  }
  return arr
}
// 后面还会多次用到,就不再写出来了
function swap(arr, n, m) {
    
    
  [arr[n], arr[m]] = [arr[m], arr[n]]
}

三、选择排序 Selection Sort(O(n²))

大致流程:
1.取出未排序部分的第一个元素,遍历该元素之后的部分并比较大小。对于第一次遍历,就是取出第一个元素
2.如果有更小的,与该元素交换位置
3.每次遍历都能找出剩余元素中的最小值并放在已排序部分的最后
注:并不是倒着的冒泡排序。冒泡排序是比较相邻的两个元素
演示图:
在这里插入图片描述

function selectionSort(arr) {
    
    
  for (let i = 0; i < arr.length; i++) {
    
    
    let min_index = i
    // 遍历后面的部分,寻找更小值
    for (let j = i + 1; j < arr.length; j++) {
    
    
      // 如果有,更新min_index
      if (arr[j] < arr[min_index]) min_index = j
    }
    swap(arr, i, min_index)
  }
  return arr
}

四、插入排序 Insertion Sort(O(n²))

大致流程:
1.从数组的第二个数据开始往前比较,即一开始用第二个数和他前面的一个比较,如果 符合条件(比前面的大或者小,自定义),则让他们交换位置。
2.然后再用第三个数和第二个比较,符合则交换,但是此处还得继续往前比较,比如有 5个数8,15,20,45, 17, 17比45小,需要交换,但是17也比20小,也要交换,当不需 要和15交换以后,说明也不需要和15前面的数据比较了,肯定不需要交换,因为前面的数据都是有序的。
3.重复2,一直到数据全都排完。
演示图:
在这里插入图片描述
代码实现:

function insertionSort(arr) {
    
    
  for (let i = 0; i < arr.length; i++) {
    
    
    // 对前面的已排序数组和新选出来的元素执行一趟冒泡排序
    for (let j = i + 1; j >= 0; j--) if (arr[j] < arr[j - 1]) swap(arr, j, j - 1)
  }
  return arr
}

五、快速排序 Quick Sort(O(nlogn))

实现过程:
1.选择一个基准元素 index,比如第一个元素
2.当然可以选其他元素,但是最后会递归至只剩一个元素,所以还是选第一个元素比较靠谱
3.遍历数组,比 index 更小的元素创建一个数组,更大的创建一个数组,相等的也创建一个数组
递归大小两个数组,继续执行1,直到数组只剩1个元素(递归出口);递归的同时把这三部分连接起来

在这里插入图片描述

代码如下:

let arr = [2,5,7,0,1,4]
    function quickSort(arr) {
    
     
      // 递归出口
      if(arr.length<=1) return arr
      //选取一个标记值
      let base = arr[0]
      // 创建左小右大两个数组,以及包含标记值的数组
      let left = []
      let right = []
      let middle = [base]
      for(let index = 1;index<arr.length;index++){
    
    
        if(arr[index]===base) middle.push(arr[index])
        else if(arr[index]<base) left.push(arr[index])
        else right.push(arr[index])
      }
      // 递归调用quickSort
      return quickSort(left).concat(middle,quickSort(right))
    }
    console.log(quickSort(arr));

参考:https://juejin.cn/post/6844903814340804615
https://zhuanlan.zhihu.com/p/114851128
https://segmentfault.com/a/1190000008712244

猜你喜欢

转载自blog.csdn.net/weixin_44019523/article/details/114005437