深入探索JavaScript中的5种经典算法

2023-08-20 00:42:43

在本文中,您将了解到:
冒泡排序、快速排序等常见排序算法原理及其在 JavaScript 中的实现;

在这里插入图片描述

经典算法示例

1. 冒泡排序算法

冒泡排序算法:冒泡排序是一种简单但效率较低的排序算法。它通过多次遍历数组,比较相邻元素并交换位置来实现排序。

原理图示

在这里插入图片描述

js实现

function bubbleSort(arr) {
  const len = arr.length;
  for (let i = 0; i < len - 1; i++) {
    // 每次遍历比较相邻元素并交换位置,将最大的元素移到末尾
    for (let j = 0; j < len - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        // 使用解构赋值进行元素交换
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  
 return arr;
}
// 示例用法:
const numbers = [4, 2, 6, 8, 3];
console.log(bubbleSort(numbers)); // 输出: [2,3,4,6,8]

bubbleSort 函数接受一个数组作为参数,并使用嵌套循环遍历数组来执行冒泡排序。内部循环通过比较相邻元素并根据需要交换它们的位置来实现排序。外部循环控制总共要进行多少轮排序操作。

2. 快速排序算法

快速排序算法:快速排序是一种高效的分治算法。它选择一个基准元素,并将数组分成两个子数组,其中一个小于基准值,另一个大于基准值。然后递归地对这两个子数组进行快速排序。

原理图示

在这里插入图片描述

js实现

function quickSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }
  
  const pivot = arr[Math.floor(arr.length / 2)]; // 选择数组中间元素作为基准值
  const left = [];
  const right = [];

   for (let i =0; i<arr.length;i++){
     if(i!== Math.floor(arr.length/2)){
       if(arr[i]<pivot){
         left.push(arr[i]);
       } else{
          right.push(arr[i]);
       }
     } 
   }

   return [...quickSort(left),pivot,...quickSort(right)];
}
// 示例用法:
const numbers = [4, 2, -3, 6, -8];
console.log(quickSort(numbers)); // 输出: [-8,-3,2,4,6]

quickSort 函数接受一个数组作为参数,并通过递归方式实现快速排序。首先选择数组中间的元素作为基准值(也可以选择其他位置),然后将小于基准值的元素放入左侧数组 left,大于等于基准值的元素放入右侧数组 right。最后,使用递归调用对左右子数组进行快速排序,并合并结果。

3. 二分查找算法

二分查找算法:二分查找是在有序数组中查找特定元素的常用方法。它通过将目标值与数组中间元素进行比较,并根据比较结果缩小搜索范围直到找到目标值或确定不存在。

原理图示

在这里插入图片描述

js实现

function binarySearch(arr, target) {
  let left = 0;
  let right = arr.length - 1;

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

     if (arr[mid] === target) {
      return mid; // 找到目标元素,返回索引位置
    } else if (arr[mid] < target) {
      left = mid + 1; // 目标在右侧子数组中
    } else {
      right = mid - 1; // 目标在左侧子数组中
    }
  }

   return -1; // 没有找到目标元素,返回-1表示失败
}
// 示例用法:
const numbers = [2, 4, 6, 8,10];
console.log(binarySearch(numbers,6)); // 输出: 2

binarySearch 函数接受一个已排序的数组 arr 和目标值 target。通过不断将搜索范围缩小至左半部分或右半部分来实现二分查找。

4. 阶乘函数

阶乘函数用于计算给定数字 n 的阶乘(n!)。递归和迭代都可以实现该功能。

原理图示

在这里插入图片描述

js实现

function factorial(n) {
  if (n === 0 || n === 1) {
    return 1; // 当输入为0或1时,直接返回1
  } else {
    return n * factorial(n - 1); // 使用递归计算阶乘
  }
}

// 示例用法:
console.log(factorial(5)); // 输出: 120

factorial 函数接受一个非负整数 n 参数,并通过递归方式计算其阶乘。当输入值为0或1时,直接返回结果为1;否则,在每一次递归调用过程中,将当前参数 n 和 n-1 相乘。重复这个过程直到 n 值减至0或者1。

5. 斐波那契数列

斐波那契数列:斐波那契数列是由前两个数字开始,并且每个后续数字都等于前两个数字之和的序列。使用递归或循环方法都可以生成斐波那契数列。

原理图示

在这里插入图片描述

js实现

function fibonacci(n) {
  if (n === 0) {
    return 0; // 当输入为0时,直接返回0
  } else if (n === 1 || n === 2) {
    return 1; // 当输入为1或2时,直接返回1
  } else {
    let a = 1;
    let b = 1;

     for (let i = 3; i <= n; i++) {
      const temp = a + b;
      a = b;
      b = temp;
    }

     return b; // 返回第n个斐波那契数列的值
 }
}
// 示例用法:
console.log(fibonacci(6)); // 输出:8

fibonacci 函数接受一个非负整数 n 参数,并通过迭代方式计算其对应位置上的斐波那契数。当输入值为0时,直接返回结果为0;当输入值为1或2时,也直接返回结果为1;否则,在每一次迭代过程中利用两个变量 a 和 b 来保存当前位置和前一个位置的斐波那契数。通过不断更新这两个变量来求解下一个位置上的斐波那契数。

总结

算法的使用意义:

  1. 提高性能:使用高效的算法可以提升程序的执行效率。例如,对大型数据集进行排序时,使用快速排序比简单的冒泡或选择排序更有效率。
  2. 数据处理与查询:搜索算法允许我们在给定数据集中查找特定元素。例如,通过二分查找可以快速地在已经排好序的数组中查找目标值。
  3. 优化资源利用:某些问题可能存在重复计算或者多次使用相同结果的情况。递归和动态规划是解决这类问题非常有用的方法。它们可以帮助我们避免重复计算,并且将问题拆解为子问题来求解,从而节省时间和资源。
  4. 程序设计思维培养:学习和理解常见算法可以培养抽象化思考能力以及良好的程序设计习惯。熟悉各种类型的问题并掌握相应的解决方案,有助于编写清晰且可扩展性高的代码。
  5. 面试和竞争力:在面试过程中,算法问题是常见的考察点。掌握常见算法并能够灵活运用,可以提升求职竞争力,并展示自己的技术水平。
更多推荐

PHP 如何创建一个 composer 包 并在 项目中使用自己的 composer sdk 包

第一步创建一个composerSDK项目创建一个composer.json文件或使用命令(如果不清楚怎么弄直接跳过即可,一般都会默认配置)composerinit这是生成的composer.json文件将自己要使用的包添加到require中,如果没有require则自己添加(composer文件中必须用双引号不能使用单

加密货币交易所偿付能力的零知识证明

如何检测下一个FTX和Mt.Gox加密货币交易所FTX的内爆导致数十亿客户资金流失,这是加密货币历史上交易所破产的最新例子。历史可以追溯到2014年,当时处理70%比特币交易的历史最悠久、规模最大的交易所Mt.Gox丢失了用户的850,000个比特币。如今,许多用户更喜欢将他们的加密货币资产存储在集中式交易所中,以便于

区块链交易平台开发流程

随着区块链技术的日益发展,越来越多的金融机构和创业公司开始探索开发区块链交易平台的潜力。以下是一篇关于区块链交易平台开发流程的指南。一、理解区块链技术在开发区块链交易平台之前,必须深入理解区块链技术的内在机制和原理。区块链是一种分布式数据库,通过去中心化和去信任的方式维护可靠的数据记录,使得任何达成一致的双方能够直接进

springboot和vue:三、web入门(spring-boot-starter- web+控制器+路由映射+参数传递)

spring-boot-starter-webSpringBoot将传统Web开发的mvc、json、tomcat等框架整合,提供了spring-boot-starter-web组件,简化了Web应用配置。创建SpringBoot项目勾选SpringWeb选项后,会自动将spring-boot-starter-web组

Android 回声消除

Android回声消除前言在语音聊天、语音通话、互动直播、语音转文字类应用或者游戏中,需要采集用户的麦克风音频数据,然后将音频数据发送给其它终端或者语音识别服务。如果直接使用采集的麦克风数据,就会存在回音问题。所谓回音就是在语音通话过程中,如果用户开着扬声器,那么自己讲话的声音和对方讲话的声音(即是扬声器的声音)就会混

c++基础:new函数

new函数new是用于动态分配内存的操作符。它用于在堆内存中创建一个新的对象或数据结构,并返回一个指向该内存的指针。这是C++中进行动态内存分配的主要方式之一,通常与delete操作符一起使用来释放先前分配的内存。以下是使用new操作符的一些示例:动态分配一个整数,并将其赋值给指针:int*pInt=newint;*p

Python基础运算分享

Python的运算符和其他语言类似(我们暂时只了解这些运算符的基本用法,方便我们展开后面的内容,高级应用暂时不介绍)数学运算>>>print1+9#加法>>>print1.3-4#减法>>>print3*5#乘法>>>print4.5/1.5#除法>>>print3**2#乘方>>>print10%3#求余数判断判断是

抖音开网店无货源怎么找

随着社交媒体的快速发展,抖音已经成为了一种极具潜力的电商平台。许多人想要利用这个平台开设网店,但是其中很多人面临的问题是如何找到货源。无货源的抖音网店经营固然具有一定的难度,但并非不可行。以下是一些帮助你在抖音开网店无货源的方法。代销合作:寻找与制造商或批发商的代销合作是一种常见的方式。你可以与他们签订协议,销售他们的

1787_函数指针的使用

全部学习汇总:GitHub-GreyZhang/c_basic:littlebitsofc.前阵子似乎写了不少错代码,因为对函数指针的理解还不够。今天晚上似乎总算是梳理出了一点眉目,在先前自己写过的代码工程中做一下测试。先前实现过一个归并排序算法,算法函数的一个传入参数是指向一个比较功能函数的指针。当时进行代码实现的时

数据治理-数据存储和操作-数据架构类型

数据库可以分为集中式数据库和分布式数据。集中式系统管理单一数据库,而分布式系统管理多个系统上的多个数据库。分布式系统组件可以根据组件系统的自治性分为两类:联邦的和非联邦的。集中式数据库集中式数据库将所有数据存放在一个地方的一套系统中,所有用户连接到这套系统进行数据访问。对某些访问受限的数据来说,集中化可能是理想的,但对

如何在Spring Boot中配置双数据源?

如何在SpringBoot中配置双数据源?背景双数据源优点技术用法添加依赖配置数据源创建实体类和存储库配置数据源和实体管理器配置事务管理器实现双数据源背景在许多应用程序中,可能会遇到需要连接多个数据库的情况。这些数据库可以是不同的类型,例如关系型数据库和NoSQL数据库,或者它们可以是相同类型但包含不同的数据。为了处理

热文推荐