JavaScript排序算法大解密 - 冒泡、选择、插入、快速排序全解析


✨ 前言

排序是计算机科学中一个经典的问题。良好的排序算法可以大大提高程序的性能。本文将全面解析几种JavaScript中的经典排序算法实现,包括冒泡排序、选择排序、插入排序和快速排序。通过示例代码和逻辑说明,你将学会这些排序算法的基本思路,时间和空间复杂度,以及如何在JavaScript中实现。排序算法的精妙之处在于充分利用数据结构,通过巧妙的交换与比较来完成排序,值得每一位计算机从业者细细品读。本文将由浅入深,从排序原理说明到具体代码实现,帮你深入掌握这些精巧的算法。相信通过学习本文,你将可以熟练掌握各类排序算法的JS实现,在未来的编程工作中运用自如,对于提升你的数据结构与算法能力大有裨益。那么,让我们开始JavaScript排序算法的奥秘之旅吧!

冒泡排序

function bubbleSort(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]) {
        let temp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = temp;
      }
    }
  }
  return arr;
}

let arr = [5, 2, 4, 6, 1, 3];
console.log(bubbleSort(arr)); // [1, 2, 3, 4, 5, 6]

冒泡排序是一种简单的排序算法,它的基本思想是通过反复比较和交换相邻元素,使较大的元素逐渐“浮”到数组的末尾,就像气泡一样逐渐上浮。

冒泡排序的详细步骤是:

  1. 从数组开头开始,比较相邻的两个元素,如果顺序是反的(第一个比第二个大),则交换它们的位置。
  2. 对每一对相邻元素都进行同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

可以通过一个示例数组来理解冒泡排序的过程:

原数组:[5, 1, 4, 2, 8]

  1. 第一轮:[1, 5, 4, 2, 8] (5和1交换位置)
  2. 第二轮:[1, 4, 5, 2, 8] (5和4交换位置)
  3. 第三轮:[1, 4, 2, 5, 8] (5和2交换位置)
  4. 第四轮:[1, 4, 2, 5, 8] (已排序完成)

从上面的过程可以看出,冒泡排序通过交换相邻不符合顺序的元素位置,让较大的元素向上逐步“浮动”,每一轮下来最大的元素都会被交换到最后的位置,直到数组完全有序。

冒泡排序的时间复杂度在最坏情况下是O(n^2),因为有两个嵌套的循环。空间复杂度为O(1),只需要一个临时变量用于交换。冒泡排序的主要优点是算法简单,但是它的效率较低,通常只适用于小规模的排序。对于大数据量,会有更优的算法选择,如快速排序等。

选择排序

function selectionSort(arr) {
  for (let i = 0; i < arr.length; i++) {
    let minIndex = i;
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[minIndex]) {
        minIndex = j; 
      }
    }
    let temp = arr[i]; 
    arr[i] = arr[minIndex];
    arr[minIndex] = temp;
  }
  return arr;
}

let arr = [5, 3, 6, 2, 10];
console.log(selectionSort(arr)); // [2, 3, 5, 6, 10]

选择排序是一种简单直观的排序算法。它的工作原理是:

  1. 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  2. 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  3. 重复第二步,直到所有元素均排序完毕。

举例:

原数组:[5, 3, 6, 2, 10]

  1. 第一轮:将3与5交换位置,得到[3, 5, 6, 2, 10]
  2. 第二轮:将2与5交换位置,得到[3, 2, 6, 5, 10]
  3. 第三轮:将2与6交换位置,得到[2, 3, 6, 5, 10]

可以看出,选择排序通过找到未排序的最小值,放到已排序序列的末尾,经过n-1轮后得到有序序列。

选择排序时间复杂度为O(n^2),因为需要两层循环来选择最小值。空间复杂度为O(1)。

选择排序由于简单, Performance也比冒泡排序好,但仍是O(n^2)的复杂度。它适合对小规模数组排序。对于大数据量,也有更优的排序算法选择。

选择排序的主要优点是比较次数少,对于大规模数组,交换所需时间少,然而步骤单一,各轮排序并无交叉进行,速度较慢。可以适当优化算法提高速度。

插入排序

function insertionSort(arr) {
  for (let i = 1; i < arr.length; i++) {
    let curr = arr[i];
    let j = i - 1;
    while (j >= 0 && curr < arr[j]) {
      arr[j + 1] = arr[j];
      j--;
    }
    arr[j + 1] = curr;
  }
  return arr;
}

let arr = [5, 2, 4, 6, 1, 3];
console.log(insertionSort(arr)); // [1, 2, 3, 4, 5, 6]

插入排序的工作原理是,将数组分为两个部分,前面部分是有序的,后面部分是无序的。每次从无序部分取出第一个元素,并把它插入到有序部分中的正确位置。

插入排序包含以下步骤:

  1. 从第一个元素开始,该元素可以认为已经被排序。
  2. 取出下一个元素,在已排序的元素序列中从后向前扫描。
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置。
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置。
  5. 将新元素插入到该位置后。
  6. 重复步骤2~5。

例如对数组[5,2,4,6,1,3] 排序:

  1. 第一轮:取出2,插入有序序列[5],变为 [2,5]
  2. 第二轮:取出4,插入有序序列[2,5],变为[2,4,5]
  3. 第三轮:取出6,插入有序序列[2,4,5],变为[2,4,5,6]
  4. 第四轮:取出1,插入有序序列[2,4,5,6],变为[1,2,4,5,6]
  5. 第五轮:取出3,插入有序序列[1,2,4,5,6],变为[1,2,3,4,5,6]

可以看出,插入排序逐步构建有序序列,对于少量元素的数组,插入排序能够有效减少交换和移动次数。

插入排序的时间复杂度是O(n^2),空间复杂度为O(1)。相比冒泡排序和选择排序,插入排序能够更快地对部分有序数组进行排序。因此适合对小规模数组排序。

文末

技术是没有终点的,也是学不完的,最重要的是活着、不秃。

零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。

最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。

自学最怕的就是缺乏自驱力,一定要自律,杜绝“三天打鱼两天晒网”,到最后白忙活一场。

高度自律的同时,要保持耐心,不抛弃不放弃,切勿自怨自艾,每天给自己一点点鼓励,学习的劲头就会很足,不容易犯困。

技术学到手后,找工作的时候一定要好好准备一份简历,不要无头苍蝇一样去海投简历,容易“竹篮打水一场空”。好好的准备一下简历,毕竟是找工作的敲门砖。

拿到面试邀请后,在面试的过程中一定要大大方方,尽力把自己学到的知识舒适地表达出来,不要因为是自学就不够自信,给面试官一个好的印象,面试成功的几率就会大很多,加油吧,骚年!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值