当前位置: 首页 > news >正文

基础数据结构和算法《》

递归 

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-15 * (4*fn(3))     参数n = 4-15 * 4 * (3*fn(2))  参数n = 3-15 * 4 * 3 * (2*fn(1)) 参数n =2-11.2.推到成递归公式 fn(n) = n*fn(n-1) ,且fn(1) = 11.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} = arraylet indexMinfor (let i = 0; i < length-1; i++) {// 等价替换indexMin = ifor (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数据结构与算法 · 看云

相关文章:

基础数据结构和算法《》

递归 1.递归应该一种比较常见的实现一些特殊代码逻辑时需要做的&#xff0c;但常常也是最绕的一种方式&#xff0c;在解释递归 之前&#xff0c;我们用循环和递归来做个比较1.1.如果你打开一扇门后&#xff0c;同样发现前方也有一扇们&#xff0c;紧接着你又打开下一扇门...直…...

[设计模式Java实现附plantuml源码~行为型]对象间的联动~观察者模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…...

vue3+js 实现记住密码功能

常见的几种实现方式 1 基于spring security 的remember me 功能 ​​​​​​​ localStorage 除非主动清除localStorage 里的信息 &#xff0c;不然永远存在&#xff0c;关闭浏览器之后下次启动仍然存在 存放数据大小一般为5M 不与服务器进行交互通信 cookies 可以…...

基于单片机的太阳能电池板自动跟踪系统的研究

摘要 伴随着人类社会的发展,人口基数越来越大,电量消耗巨大,传统发电原 料污染环境的同时,可用量日益减少,给人类未来生产生活带来了一定的威胁, 因而解决日益剧增的用电量,寻求一种新能源显得极其重要。论文正是基于此 背景下,针对当前太阳能电池板采光率低、自动化水…...

React 模态框的设计(二)

自定义组件是每个前端开发者必备的技能。我们在使用现有框架时难免有一些超乎框架以处的特别的需求&#xff0c;比如关于弹窗&#xff0c;每个应用都会用到&#xff0c;但是有时我们使用的框架中提供的弹窗功能也是功能有限&#xff0c;无法满足我们的应用需求&#xff0c;今天…...

操作符详解3

✨✨ 欢迎大家来到莉莉的博文✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 前面我们已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作 符&#xff0c;今天继续介绍一部分。 目录 1.操作符的分类 2…...

【C语言基础】:操作符详解(一)

文章目录 操作符详解1. 操作符的分类2. 二进制和进制转换2.1 什么是二进制、八进制、十进制、十六进制2.1.1 二进制和进制转换2.1.2 二进制转十进制2.2.3 二进制转八进制2.2.4 二进制转十六进制 3. 源码、反码、补码4. 移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&…...

通俗易懂分析:Vite和Webpack的区别

1、对项目构建的理解 先从浏览器出发&#xff0c; 浏览器是由浏览器内核和JS引擎组成&#xff1b;浏览器内核编译解析html代码和css代码&#xff0c;js引擎编译解析JavaScript代码&#xff1b;所以从本质上&#xff0c;浏览器只能识别运行JavaScript、CSS、HTML代码。 而我们在…...

OpenCart程序结构与业务逻辑

一、程序业务逻辑说明 在 OpenCart 中&#xff0c;index.php 文件是整个应用程序的入口文件&#xff0c;它负责初始化应用程序并调度请求。以下是 index.php 文件加载执行的流程&#xff1a; 1. **设置路径常量&#xff1a;** - index.php 首先定义了一些重要的路径常量&…...

软件License授权原理

软件License授权原理 你知道License是如何防止别人破解的吗?本文将介绍License的生成原理,理解了License的授权原理你不但可以防止别人破解你的License,你甚至可以研究别人的License找到它们的漏洞。喜欢本文的朋友建议收藏+关注,方便以后复习查阅。 什么是License? 在…...

C/C++实现老鼠走迷宫

老鼠形象可以辨认&#xff0c;可以用上下左右操纵老鼠;正确检测结果&#xff0c;若老鼠在规定的时间内走到粮仓&#xff0c;提示成功&#xff0c;否则提示失败。代码分为3个文件&#xff1a;main.cpp、play.h、play.cpp。 main.cpp: #include <iostream> #include <…...

[Linux]文件基础-如何管理文件

回顾C语言之 - 文件如何被写入 fopen fwrite fread fclose fseek … 这一系列函数都是C语言中对文件进行的操作&#xff1a; int main() {FILE* fpfopen("text","w");char str[20]"write into text";fputs(str,fp);fclose(fp);return 0; }而上…...

bat 查找文件所在

脚本 在批处理文件&#xff08;.bat&#xff09;中查找文件所在的目录&#xff0c;你可以使用dir命令结合循环和条件语句来实现。以下是一个简单的示例&#xff0c;演示如何在批处理文件中查找指定文件并输出其所在目录&#xff1a; echo off setlocal enabledelayedexpansio…...

程序员的守护神:为何电脑永不熄灭?

在这个信息时代&#xff0c;程序员成了推动社会进步的“隐形英雄”。他们通宵达旦&#xff0c;手指在键盘上跳跃&#xff0c;创造出一个个令人惊叹的数字世界。有趣的是&#xff0c;你可能注意到了一个现象&#xff1a;程序员似乎总是不关电脑。这并非他们对电脑上瘾&#xff0…...

Kafka快速实战以及基本原理详解

Kafka快速实战以及基本原理详解 基本概念 Kafka是一个分布式、支持分区、多副本&#xff0c;基于ZK的分布式消息系统&#xff0c;最大的特性就是可以实时的处理大量数据以满足各种需求场景&#xff0c;比如Hadoop的批处理系统、低延迟的实时系统、Storm/Spark流式处理引擎、日…...

微信小程序(4)- 事件系统和模板语法

1. 事件系统 1.1 事件绑定和事件对象 小程序中绑定事件与在网页开发中绑定事件几乎一致&#xff0c;只不过在小程序不能通过 on 的方式绑定事件&#xff0c;也没有 click 等事件&#xff0c;小程序中绑定事件使用 bind 方法&#xff0c;click 事件也需要使用 tap 事件来进行代…...

【Java多线程】对线程池的理解并模拟实现线程池

目录 1、池 1.1、线程池 2、ThreadPoolExecutor 线程池类 3、Executors 工厂类 4、模拟实现线程池 1、池 “池”这个概念见到非常多&#xff0c;例如常量池、数据库连接池、线程池、进程池、内存池。 所谓“池”的概念就是&#xff1a;&#xff08;提高效率&#xff09; 1…...

python连接mysql数据库

连接MySQL数据库&#xff0c;通常我们会使用Python的mysql-connector-python库。下面是一个基本的示例来展示如何使用Python连接到MySQL数据库。 首先&#xff0c;确保你已经安装了mysql-connector-python库。如果没有&#xff0c;你可以使用pip来安装它&#xff1a; pip ins…...

docker用法

首先需要去docker官网注册你的账号&#xff0c;记住账号名称和密码&#xff1b; 然后在本地执行&#xff1a; docker login登录OK。 把ubuntu下载到本地&#xff1a; sudo docker pull ubuntusudo docker images输出&#xff1a; REPOSITORY TAG …...

DIcom调试Planar configuration

最近和CBCT组同事调dicom图像 这边得图像模块老不兼容对方得dicom文件。 vtk兼容&#xff0c;自己写得原生解析不兼容。 给对方调好了格式&#xff0c;下次生成文件还会有错。 简单记录下&#xff0c;日后备查。 今天对方又加了 个字段&#xff1a;Planar configuration 查…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...