前端 js 经典:递归

news2025/10/26 3:52:40

1. 什么是递归

函数内部调用自己,这就是递归

2. 为什么用递归

对数据进行处理,优化处理流程可以用递归

3. 构成递归三要素(必须)

3.1 参数递归逻辑:内部函数对比外部函数参数递归的逻辑,如下例,demo(n-1)对比 demo(n)参数递归逻辑为 n-1

3.2 临界值:参数到达临界值后,不再递归,如下例,n == 0,不再递归

3.3 递归业务逻辑:你需要递归来做什么,如下例,n + demo(n-1),0 到 n 求和

// 例子
function demo(n) {
  if (n == 0) return 0;
  return n + demo(n - 1);
}

4. 经典递归案例

// 4.1:0 到 n 求和
function sum(n) {
  // sum(n-1) n-1 为参数递归的逻辑
  // n == 1 为临界值
  // n + sum(n-1) 为递归业务逻辑

  if (n == 1) return 1;
  return n + sum(n - 1);
}
sum(100); // 5050

// 4.2:数组扁平化
// 将[1, [2, 3], [4, [5, 6]], 7]转换为[1, 2, 3, 4, 5, 6, 7]
function flattenArray(arr) {
  // arr.forEach(item => { flattenArray(item) }) 数组遍历的item,为参数递归的逻辑
  // !Array.isArray(item) 不是数组时,为临界值
  // resultArr.push(...flattenArray(item)) 将数组拼接起来, 为递归业务逻辑

  const resultArr = [];
  arr.forEach((item) => {
    if (!Array.isArray(item)) {
      resultArr.push(item);
    } else {
      resultArr.push(...flattenArray(item));
    }
  });
  return resultArr;
}
flattenArray([1, [2, 3], [4, [5, 6]], 7]); // [1, 2, 3, 4, 5, 6, 7]

// 4.3:深拷贝
function deepClone(obj) {
  // for (const key in obj) { deepClone(obj[key]) } 遍历的obj[key],为参数递归的逻辑
  // typeof v === "object" && v !== null 是对象类型且不为null继续递归,反之则为临界值
  // target[key] = deepClone(v) 为递归业务逻辑

  // 拷贝数据不是对象类型直接返回
  if (typeof obj !== "object") return obj;
  const target = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    // 判断数据中key是否重复,不重复着继续逻辑
    if (!hasOwnProperty.call(obj, key)) continue;
    const v = obj[key];
    target[key] = typeof v === "object" && v !== null ? deepClone(v) : v;
  }
  return target;
}

// 4.4:斐波拉契数列
// 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...求第 n 项
function fib(n) {
  // fib(n-1),fib(n-2) 第n位数为第n-1位数+第n-2位数,n-1,n-2为参数递归的逻辑
  // n == 1 || n == 2 第1位数为1,第二位数为1,n==1,n==2为临界值
  // fib(n-1) + fib(n-2) 第n位数为第n-1位数+第n-2位数,为递归业务逻辑

  if (n == 1 || n == 2) return 1;
  return fib(n - 1) + fib(n - 2);
}

// 4.5:爬楼梯
// 一个人爬楼梯,只可以一步走1层或一步走2层,到达n层,一共多少种走法?
// 1, 2, 3, 5, 8; 爬1层1种走法,2层2种,3层3种,4层5种,5层8种,...n层n-1层+n-2层走法
function climbStairs(n) {
  // n-1,n-2 为参数递归的逻辑
  // n == 1 || n ==2 为临界值
  // climbStairs(n-1) + climbStairs(n-2) 为递归业务逻辑

  if (n == 1 || n == 2) return n;
  return climbStairs(n - 1) + climbStairs(n - 2);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1114252.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

接口测试(jmeter和postman 接口使用)

接口测试基础知识 接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。把前端(client)和后端(server)联系起来,测试的重点是要检查数据的交换,传递和控制管理过程,以及系…

Keeplived安装部署(单机双机)

Keeplived官网:https://www.keepalived.org/download.html 一 单机安装配置: 1.上传keepalived安装包并且安装 [rootmaster1 local]# tar -zxvf keepalived-2.2.8.tar.gz [rootmaster1 local]# mv keepalived-2.2.8 keepalived [rootmaster1 local]# chown root:r…

docker安装es分词插件ik详情步骤

1.下载ik查询 根据es版本去下载对应的版本,游览器中输入下面下载链接 https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.7.1/elasticsearch-analysis-ik-8.7.1.zip 2.2.若有对应版本跳过,若没有对应版本(比如我需…

将语义分割的标注mask转为目标检测的bbox

1. 语义分割标签 1.1 labelme工具 语义分割的标签是利用labelme工具进行标注的,标注的样式如下: 1.2 语义分割的标签样式 2. 转换语义分割的标注到目标检测的bbox 实现步骤 (1) 利用标注的json文件生成mask图片(2) 在mask图片中找到目标的bbox矩形框的左上角点和右下角点(…

TCP通信-使用线程池优化

下面的通信架构存在问题: 客户端与服务端的线程模型是: N-N的关系,客户端并发越多,系统瘫痪的越快。 引入线程池处理多个客户端消息 代码实现 public class ClientDemo1 {public static void main(String[] args) {try {Syste…

C++是不是最容易产生猪队友的编程语言之一?

C是不是最容易产生猪队友的编程语言之一? 猪队友不是什么编程语言产生的,而是其做派本身就是猪队友,比如说自己一知半解的东西用得飞 起,而且不愿意深层次去学;再比如说不愿意写单元测试,甚至普通的测试都懒得做。最近…

在chrom浏览器安装Vue.js devtools插件,遇到恶意扩展程序字样,附百度网盘下载链接

遇到的问题 拖拽下载好的 Vue.js devtools 插件到谷歌扩展程序, 百度网盘下载地址 链接:https://pan.baidu.com/s/1FeK6pwc2UzRUUlMFN3rW5w?pwdw361 提取码:w361 提示: 解决办法 将Vue.js devtools 插件的后缀从.crx改为.zi…

C# 文件 校验:MD5、SHA1、SHA256、SHA384、SHA512、CRC32、CRC64

文件 校验 算法:MD5、SHA1、SHA256、SHA384、SHA512、CRC32、CRC64 编程语言:C# 文件属性内容 校验算法:MD5、SHA1、SHA256、SHA384、SHA512、CRC32、CRC64。 核心代码: using System; using System.Collections.Generic; using System; using System.Text; using Syst…

提升APP的用户体验的方法

提高APP的用户体验(User Experience,简称UX)对于吸引用户、提高用户满意度和应用的成功至关重要。以下是一些方法,可以帮助改善APP的用户体验,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包…

K8s 概念及组件

K8s 的全称为Kubernetes,是一种开源的容器编排平台,用于自动化部署以及扩展和管理容器化的应用程序,它提供了一种容器编排和管理的方式,可以帮助开发人员更轻松的管理容器化的应用程序,并且提供了一种跨多个主机的自动…

内存爆炸、CPU100%问题定位

目录 一、内存爆炸相关1、关于-Xms(最小堆内存)和-Xmx(最大堆内存)2、JVM初始化时申请实际物理内存3、OutOfMemory问题排查(1) 堆内存溢出排查(2) 堆外内存溢出排查 二、CPU 100及死锁问题定位1、CPU 100问题排查(1) 找到程序对应进程号(2) 查找进程对应的线程编号(3)查看线程堆…

根据Excel表格数据去修改数据库数据

一、背景 项目上线,实施任务发来一份Excel表格数据 需要将供应商和生产厂商进行绑定,因为数据过多,实施人员一个个绑定时间成本过高,想让开发给出一个脚本。 二、操作 比如这些数据 生产厂商为A 供应商为B 以update 语句为例 …

基于Vertx实现可配置及可扩展的IOT服务

搭建框架的目标 相信写过IOT服务的伙伴应该知道,面对各种千奇百怪的通信协议,特别是16进制报文的协议,有些协议看的确实有点让人头疼。但这些协议中也有很多共性,不必针对每过协议都把一些业务无关的代码再撸一遍。 搭建这个项目主…

【Javascript】‘var‘ is used instead of ‘let‘ or ‘const‘

解决: 设置完之后,var 就不会再出现黄色波浪线警告

普通二维码跳转微信小程序实战

简介 服务端springboot项目,前端基于uniapp的微信小程序,要求扫描二维码之后进入到小程序指定页面,下面记录一下实现过程以及过程中遇到的问题. 实现过程 下面是成功跳转的配置截图: 首先说下二维码规则,这个地方需要填写扫描二维码之后打开的地址,这个地址在我的项目里…

Keil实现Flash升级跳转(STM32/GD32/HC32)

编写BOOT程序,和APP程序。 BOOT程序检查OTA参数,执行OTA升级,然后跳转到APP代码。 记录一下跳转APP需要修改得东西: 1、BOOT程序 修改跳转地址 先检查APP地址是否有效 然后关闭外设 反初始化 设置MSP指针,进行跳转 …

多商户自营连锁小程序商城的作用是什么

近几年,线上线下经营压力很大,不少商家都希望通过数字化转型实现破局或增长,单店管理力度相对容易些,但如果是连锁门店,近几年则相对风险大些,但从2020年至今依然有不少品牌选择扩店,增加连锁规…

vue 组件封装 综合案例

vue 组件封装 综合案例 **创建 工程: H:\java_work\java_springboot\vue_study ctrl按住不放 右键 悬着 powershell H:\java_work\java_springboot\js_study\Vue2_3入门到实战-配套资料\01-随堂代码素材\day05\准备代码\11-综合案例-商品列表 vue --version vue c…

深入探索Sharding JDBC:分库分表的利器

随着互联网应用的不断发展和用户量的不断增加,传统的数据库在应对高并发和大数据量的场景下面临着巨大的挑战。为了解决这一问题,分库分表成为了一个非常流行的方案。分库分表主流的技术包括MyCat和Sharding JDBC。我们来通过一张图来了解这两者有什么区…

38 WEB漏洞-反序列化之PHPJAVA全解(下)

目录 Java中的API实现序列化和反序列化演示案例WebGoat_Javaweb靶场反序列化测试2020-网鼎杯-朱雀组-Web-think java真题复现 文章参考: https://www.cnblogs.com/zhengna/p/15737517.html https://blog.csdn.net/MCTSOG/article/details/123819548 ysoserial生成攻…