基础数据结构和算法《》

news2025/6/9 13:19:49

递归 

1.递归应该一种比较常见的实现一些特殊代码逻辑时需要做的,但常常也是最绕的一种方式,在解释递归 之前,我们用循环和递归来做个比较

         1.1.如果你打开一扇门后,同样发现前方也有一扇们,紧接着你又打开下一扇门...直到打开最后一扇门出去, 或者一直没有碰到尽头 (死循环)——'这就是循环'

        1.2.如果你打开一扇门,紧接着你又用钥匙打开了这扇门,然后你又看到一扇们...但是当你开到某扇门时, 发现前方是一堵墙无路可走了,你选择原路返回——'这就是递归'

2.通过上面的故事可以发现递归其实是两个过程

         2.1.'递'问题分解去的过程叫'递' -- 就像故事打开的门

         2.2.'归'遇到终止'递'的条件叫'归' -- 就像故事里的墙 

 满足递归的条件

1.递归是一种解决问题的方法,它从解决问题的各个小部分开始,直到解决最初的大问题。递
归通常涉及函数调用自身
2.还是上面开门的故事,你想知道你开启的第一个门,实际是距离墙的第几扇门,这个问题想要解决
根据第一条的概念进行拆分
    2.1.'分解成各个小部分',也就是我要知道我下一扇门距离墙是第几扇门
    2.2.'这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样',我想知道开启第一扇门距离墙
    是第几扇门,和我想知道下一扇门距离墙的位置是第几扇门是一样的
    2.3.'存在递归终止条件',也就这些问题一层一层解析后,直到我知道扇的位置后终止,在一个个回来数

如何编写递归 

1.写出递推公式,找到终止条件
2.写递归代码的关键就是找到如何将大问题分解为小问题的规律,并且基于此写出递推公式,然后再推敲终止条件,
最后将递推公式和终止条件翻译成代码
3.编写递归代码的关键是,只要遇到递归,我们就把它抽象成一个递推公式,不用想一层层的调用关系,不要试图用人
脑去分解递归的每个步骤

递归到底是个什么

1.递归就是栈一种应用场景,也遵循着'先进后出的原则(后进先出)'

 递归阶乘

1.求5*4*3*2*1 的问题,用递归来解决三步走
    1.1.分解成各个小部分
         5 * fn(4)   参数n = 5-1
         5 * (4*fn(3))     参数n = 4-1
         5 * 4 * (3*fn(2))  参数n = 3-1
         5 * 4 * 3 * (2*fn(1)) 参数n =2-1
    1.2.推到成递归公式 fn(n) = n*fn(n-1) ,且fn(1) = 1
    1.3.终止条件 fn(1) = 1


// 代码
1.递归是栈的结构表现,所以它'递'的过程是在做压栈,'归'的过程在做出栈,其实本质,先算的是
终止条件,然后在依次向上传递
2.如图一,通过浏览器的控制台可以更形象的看出这个过程

function factorial(n){
    console.trace()
    if(n === 1 || n === 0){
        return 1
    }
    console.log(n)
    return n * factorial(n-1)
}
factorial(5)

 斐波那契数列

0,1,1,2,3,5,8,13,21
// 斐波那契数列
function fibonacciIterative(n){
  if(n < 1) return 0  // 结束条件
  if(n <=2) return 1 // 结束条件
  return fibonacciIterative(n-2) + fibonacciIterative(n-1) // 递归公式 fn(n) = fn(n-1)+fn(n-2)
}


这段代码是一个使用递归方式求解斐波那契数列的函数。该函数接收一个整数参数 n,表示要求解的斐波那契数列的第 n 项(n 从 1 开始计数)。

首先判断 n 是否小于 1,如果是,则返回 0;如果 n 小于等于 2,返回 1,这两个条件是递归的结束条件。

如果 n 大于 2,则通过递归公式 fn(n) = fn(n-1)+fn(n-2) 计算第 n 项的值,即该项的前两项之和,继续调用 fibonacciIterative 函数求解第 n-1 和 n-2 项的值。

递归函数会不断地向下调用自身,直到满足结束条件才返回结果值。由于递归函数会反复调用自身,并且存在重复计算,因此在计算较大的斐波那契数列时,可能会出现性能问题。



// 优化的代码
1.向求解斐波那契数列时候,将求解过程图形化,可以看出,有些已经
求过的结点我们还会反复在求,如果把这些一求过的数存起来直接用,也会
提高效率

function fibonacciMemoization(n){
    const memo = [0,1]
    const fibonacci = (n) => {
        if(meno[0] != null) return memo[n]
        return memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
    }
     return fibonacci(n);
}

树 

二叉树搜索树 (快速查找)二叉树查找法

1.首先左侧节点存储(比父节点)小的值,右侧节点存储(比父节点)大的值,也就当我们每次去查的时候,
只要去比较查询节点和当前比较父节点大小,来决定他是走左面查询,还是右面查询,这样就不用去遍历
整个树

插入 

1.插入后的数据一定要符合左侧节点存储(比父节点)小的值,右侧节点存储(比父节点)大的值,因此插入的时候也是要先和根节点比较,直到找到末尾,来决定插入的值是作为叶节点左侧还是右侧

插入重复数据解决
1.二叉查找树中每一个节点不仅会存储一个数据,因此我们通过链表和支持动态扩容的数组等数据结构,把值相同的数据存储在同一个节点上
2.每个节点仍然只存储一个数据。在查找插入位置过程中,如果碰到一个节点的值,与要插入数据的值相同,就将这个要插入的数据放到这个节点的右子树,也就是说,把这个新插入的数据当作大于这个节点的值来处理

 排序

选择排序 

思路:

1.找到数据中最小值并将放到第一位,然后找到第二小的将其放到第二位

2.选择排序分成两个区间,分别是“排序区间”和“未排序区间”,选择排序每次会从“未排序区间”中找到最小元素,将其放到末尾

3.对引用图说明一下,引用第一个图中的第二个数据说明

        ‘1 5 6 3 2 4’,现在的1是排序区间,‘5 6 3 2 4’是为了排序区间,说明图虽然是5和2直接交换,但实际末尾的'4'也是比较过了的,只是图上没参与本次运算

1.这里有个思维转换,当我们求一个数组中最小值和最大值的时候,我们用等价替换的方法,只是 循环了一次,
问题来了当我们要把数组中所有的都进行排序那单单的一次循环肯定不够的,这时候就是双层for 循环
2.这里还要注意的是'选择排序'的概念,我们其实会将整个数组分成两个区域,'排序区间'和'未排序区间',其中'排序区间'
是在数组前半部分,因此已经排序过的地方肯定是不需要在进行排序因此第二层的循环条件也变成了'let j = i; j < length; j++'

    
  // 选择排序
  function selectionSort(array, compareFn = defaultCompare) {
    const {
      length
    } = array
    let indexMin
    for (let i = 0; i < length-1; i++) {
      // 等价替换
      indexMin = i
      for (let j = i; j < length; j++) {
        if (compareFn(array[indexMin], array[j]) === Compare.BIGGER_THAN) {
          indexMin = j
        }
      }
      if (i !== indexMin) {
        swap(array, i, indexMin)
      }
    }
    return array
  }

  console.log(selectionSort(array))

插入排序

1.插入排序每次排一个数组项,以此方式构建最后的排序数组。假定第一项已经排序了,接着,它和第二项进行比较第二项是应该待在原位还是插入到第一项之前呢?这样,头两项就正确排序,接着和第三项比较,以此类推
2.通俗的理解'插入排序'和'选择排序' 在整体思路方面差不多,首先'插入排序'也是将整个排序分成两个区间,分别是'排序区间'和'未排序区间',每次会从'未排序区间'中取值去以排序区间中比较,比较后将这个值插入到'以排序区间'
3.'插入排序'和'选择排序'  做个比较理解,'插入'是从'未排序区间'取值在'以排序区间去比较','选择'是从'未排序区间'
依次找到最小值放到'以排序区间'
4.如图红色区域就是'已排序区间',黄色就是'未排序'区间,依次从黄色区域取值去红色区域比较,并且将值插入到合适的红色区域

 

1.这里默认将第一个元素作为'已排序'区间中的内容,这样方便后续逻辑
2.通过过动态图来理解下面插入算法中的while逻辑,首先是吧整个数组分成两个区域
'已排序区域' 一个是 '为排序区域',第一层for是从为排序区域取出一个,'已排序区域'就是
从当前这个值往后都是以排序区域,因此while 的判断循环j 是从取点位置开始的,注意
动图插入的那个动作,如果你比我小我就把你往后移动,如果你比我大我就到大了位置,
整个while 就结束了,这个值就到了j的位置

// 插入排序
  function insertionSort(array, compareFn = defaultCompare) {
    const {
      length
    } = array;
    let temp;
    for (let i = 1; i < length; i++) {
      let j = i;
      temp = array[i];
      while (j > 0 && compareFn(array[j - 1], temp) ===
        Compare.BIGGER_THAN) {
        array[j] = array[j - 1];
        j--;
      }
      array[j] = temp;
    }
    return array;
  };
  insertionSort(array)
  console.log(array)

结构 -- 数组 · js数据结构与算法 · 看云

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

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

相关文章

应用回归分析:泊松回归

泊松回归是一种广泛用于计数数据的回归分析方法。它适用于响应变量是非负整数的情况&#xff0c;特别是当这些计数呈现出明显的离散分布时。泊松回归通过泊松分布的概率分布函数来建模计数数据&#xff0c;使其成为处理计数数据的自然选择。本文将介绍泊松回归的基本概念、应用…

石头剪刀布游戏(C语言)

题目描述 石头剪刀布游戏有 3 种出拳形状&#xff1a;石头、剪刀、布。分别用字母 A , B , C 表示。 游戏规则: 出拳形状之间的胜负规则如下&#xff1a; A > B&#xff1b;B > C&#xff1b;C > A&#xff1b;">"左边一个字母&#xff0c;表示相对优…

进程线程通信-day6

1、将信号和消息队列的课堂代码敲一遍 //发送端 #include<myhead.h>//定义一个消息结构类型 struct msgbuf {long mtype;char mtext[1024]; }; //定义一个宏&#xff0c;表示消息正文大小 #define MSGSIZE sizeof(struct msgbuf)-sizeof(long)int main(int argc, const…

PBM模型学习

本专栏着重讲解PBM学习所得&#xff0c;学习笔记、心得&#xff0c;并附有视频素材资料&#xff0c;视频详细目录如下&#xff1a; PBM相关参数解释1 PBM相关参数解释2 PBM相关案例实践1 PBM相关案例实践2 PBM相关案例实践2 PBM相关案例实践3 PBM多相流中次相界面设置1 PBM多相…

Kotlin 进阶 学习 委托

1.接口委托 package com.jmj.jetpackcomposecompositionlocal.byStudy/*** 接口委托*/ interface HomeDao{fun getAllData():List<String> }interface ADao{fun getById(id:Int):String }class HomeDaoImpl:HomeDao{override fun getAllData(): List<String> {ret…

MATLAB中的稀疏矩阵和密集矩阵

在MATLAB中&#xff0c;矩阵可以表示为密集或稀疏格式。通常&#xff0c;矩阵默认以密集格式存储&#xff0c;这意味着每个元素都明确地存储在内存中&#xff0c;无论它的值是多少。然而&#xff0c;当矩阵含有大量的零元素时&#xff0c;这种存储方式就会变得非常低效。为了更…

iOS整理 - 关于直播 - 搭建服务端

前言 其实本人一直都想自己简单做一套直播&#xff08;包括移动端和服务端&#xff09;的开发测试&#xff0c;但是之前一直做得比较迷茫。最近偶然间在来了灵感&#xff0c;瞬间解除了我很多疑惑。我会分享出来&#xff0c;希望大家一起研究下。稍后&#xff0c;我完整做好了…

ZS Associates致盛咨询是什么公司?排名怎么样?

随着商业化时代的加速演进&#xff0c;咨询公司在企业发展中的“智囊团”角色愈发突显。对于医药企业来说&#xff0c;一个优秀的咨询团队不仅可以帮助推动整体战略转型及内部改革&#xff0c;还对药品研发、营销起到优化促进作用。 那什么样的咨询企业可称之为优秀的咨询企业…

关于msvcr120.dll丢失怎样修复的详细解决步骤方法分享,msvcr120.dll文件的相关内容

在电脑使用过程中&#xff0c;我们经常遇到各种系统错误&#xff0c;其中msvcr120.dll丢失是一个常见问题。msvcr120.dll文件是Visual C Redistributable for Visual Studio 2015/2017的一个组件&#xff0c;主要用于支持某些应用程序的正常运行。当电脑出现msvcr120.dll丢失情…

SpringBoot项目启动报java.nio.charset.MalformedInputException Input length = 1解决方案

报错详情 SpringBoot启动报错java.nio.charset.MalformedInputException: Input length 1 报错原因 出现这个的原因&#xff0c;就是解析yml文件时&#xff0c;中文字符集不是utf-8的原因&#xff0c;这是maven在项目编译时&#xff0c;默认字符集编码是GBK。 解决方式 检…

多数pythoneer只知有列表list却不知道python也有array数组

数组和列表 Python中数组和列表是不同的&#xff0c;我敢断言大多数的pythoneer只知道有列表list&#xff0c;却不知道python也有array数组。列表是一个包含不同数据类型的元素集合&#xff0c;而数组是一个只能含相同数据类型的元素集合。 Python的array库是一个提供数组操作…

ORA-02062: distributed recovery received DBID 9ad10df5, expected 38cc1cd5

今晚做重启维护&#xff0c;发现节点二上报错如下 Fri Feb 23 21:47:43 2024 Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_reco_58540.trc: ORA-02062: distributed recovery received DBID 9ad10df5, expected 38cc1cd5 Errors in file /u01/app/oracl…

DTV的LCN功能介绍

文章目录 LCN简介LCN获取LCN Conflict LCN简介 Logical Channel Number&#xff08;LCN&#xff09;是数字电视系统中用于标识和组织频道的逻辑编号。LCN的目的是为了方便用户浏览和选择频道&#xff0c;使得数字电视接收设备能够根据这些逻辑编号对频道进行排序和显示。 LCN…

基于事件触发机制的孤岛微电网二次电压与频率协同控制MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 本模型质量非常高&#xff0c;运行效果完美。本模型为4机并联孤岛系统&#xff0c;在下垂控制的基础上加入二次控制&#xff0c;二次电压与频率协同控制策略利用事件触发的方法来减少控制器的更新次数。该方法…

exe4j将java项目打包为exe包(无需每台机器上安装jdk)

这里写目录标题 背景过程打jar包1、修改pom文件2、maven命令打jar包 下载exe4j工具1.首先去官网下载 exe相关配置1、填写密钥2、选择jar包格式3、设置名称以及输出exe位置4、设置图标及设置操作系统版本5、设置要导入的jar包&#xff0c;以及启动类6、设置jdk版本范围7、设置jd…

ArcgisForJS如何在线编辑ArcGIS Server发布的几何要素?

文章目录 0.引言1.ArcGIS创建几何要素2.ArcGIS Server发布几何要素3.ArcgisForJS在线编辑ArcGIS Server发布的几何要素 0.引言 ArcGIS For JS 是一种用于创建和编辑地理信息的 JavaScript 库&#xff0c;它允许用户在线编辑 ArcGIS Server 发布的几何要素。本文从ArcGIS创建几…

泰迪智能科技大模型数据智能实验室

自2022年11月ChatGPT问世以来&#xff0c;大模型开始备受关注&#xff0c;科技巨头们纷纷推出大模型实验室解决方案。大模型的价值不知在于互联网场景&#xff0c;而在于大模型能力垂直化&#xff0c;能够与具体的业务需求深度融合。 大模型实验室是在学校现有的实验室建设基础…

Vue3的computed计算属性和watch监视(四)

一、computed计算属性 <template><div class"person">姓:<input type"text" v-model"first_name"><br>名:<input type"text" v-model"last_name"><br><button click"changeFu…

推理速度暴增,Mamba终结Transformer的统治 !!

文章目录 前言 1、Transformer VS Mamba 2、Mamba 独特之处 3、序列建模中选择性的重要性 4、Mamba 性能亮点 5、开始使用 Mamba 6、Mamba 的影响 前言 在这篇关于 Mamba 的文章中&#xff0c;我们来探索这个创新的状态空间模型&#xff08;state-space model&#xff0c;SSM&…

缓存篇—缓存击穿

在很多场景下&#xff0c;我们的业务通常会有几个数据会被频繁地访问&#xff0c;比如秒杀活动&#xff0c;这类被频地访问的数据被称为热点数据。 如果缓存中的某个热点数据过期了&#xff0c;此时大量的请求访问了该热点数据&#xff0c;就无法从缓存中读取&#xff0c;直接…