有趣且重要的JS知识合集(22)树相关的算法
0、举例:树形结构原始数据

1、序列化树形结构
/*** 平铺序列化树形结构* @param tree 树形结构* @param result 转化后一维数组* @returns Array<TreeNode>*/
export function flattenTree(tree, result = []) {if (tree.length === 0) {return result}for (const node of tree) {result.push(node);if (node.children) {flattenTree(node.children, result);}}return result;
}
结果:

2、数组转化为树形结构
/*** 数组转化为树形结构(常用于后台菜单数组转换成树形结构)*/
export function arrToTree(data) {let result = []let map = new Map()data.forEach(item => {// 存入字典集里map.set(item.id, item)})data.forEach(item => {item.children = [];// 判断字典集里是否有该键let parent = map.get(item.pId)if (parent) {parent.children.push(item)} else {result.push(item)}})return result
}
结果:
3、BFS 寻找树形结构下指定节点id 上属直接或间接的祖先节点
/*** 寻找树形结构下指定节点id 上属直接或间接的祖先节点* @param {*} tree 树形结构* @param {*} id 节点id*/bfsFindAncestors(tree, id) {if (!tree?.length) return [];// 初始化队列,将根节点和空的祖先数组放入队列const queue = [{ node: tree[0], ancestors: [] }];while (queue.length > 0) {// 取出队列中的第一个节点和其祖先数组const { node, ancestors } = queue.shift();if (node.id === id) {// 找到目标节点,返回该节点及其祖先节点的数组return ancestors;}if (node.children && node.children.length > 0) {// 将当前节点添加到子节点的祖先数组中const newAncestors = [...ancestors, node];for (const child of node.children) {// 将子节点和新的祖先数组加入队列queue.push({ node: child, ancestors: newAncestors });}}}// 如果遍历完整个树都没有找到目标节点,返回空数组return [];}
4、BFS 遍历树形结构 寻找对应id的节点
/*** BFS遍历树形结构 寻找对应id的节点* @param {*} tree 树形结构* @param {*} id 节点id*/getNode(tree, id) {const queue = [...tree];while (queue.length) {const node = queue.shift();if (node.id === id) return node;if (node.children?.length) {queue.push(...node.children);}}return null;}
5、BFS 遍历树结构 给节点某属性赋值
/*** 遍历树结构 给节点某属性赋值 BFS* @param {*} tree 树形结构* @param {*} prop 属性* @param {*} value 值*/traverseTreeSetProperty(tree, prop, value) {// 定义一个队列,用于存储待处理的节点const queue = [...tree];while (queue.length > 0) {// 出队列const node = queue.shift();// 给当前节点赋值node[prop] = value;// 将当前节点的子节点入队列if (node.children && node.children.length > 0) {queue.push(...node.children);}}}
6、BFS 计算树形结构的最大宽度
/*** 计算树形结构的最大宽度 BFS* @param {*} tree 树形结构*/getMaxWidth(tree) {if (!tree || tree.length === 0) {return 0;}let maxWidth = 0;let queue = [...tree];while (queue.length > 0) {const levelSize = queue.length;maxWidth = Math.max(maxWidth, levelSize);const nextLevel = [];for (let i = 0; i < levelSize; i++) {const node = queue[i];if (node.children && node.children.length > 0) {nextLevel.push(...node.children);}}queue = nextLevel;}return maxWidth;}
7、DFS 计算树形结构的最大深度
/*** 计算树形结构的最大深度 DFS* @param {*} tree 树形结构*/getMaxDepth(tree) {const dfs = (nodes) => {// 一级节点为空,层级则为0if (!nodes?.length) return 0;let maxDepth = 1;// eslint-disable-next-linefor (const node of nodes) {const curDepth = dfs(node.children) + 1;maxDepth = Math.max(curDepth, maxDepth);}return maxDepth;}const treeHeight = dfs(tree)return treeHeight;}
8、DFS 寻找指定节点id对应的父级节点
/*** 寻找指定节点id对应的父级节点* @param {*} tree* @param {*} nodeId*/findParentByChildId(tree, nodeId) {let parentOfFirstChild = null;const dfs = (node, parent) => {if (parentOfFirstChild !== null) {return;}if (node.children && node.children.length > 0) {// eslint-disable-next-linefor (const child of node.children) {dfs(child, node);}}// 找到对应节点后,返回其父节点if (node.id === nodeId) parentOfFirstChild = parent;}// eslint-disable-next-linefor (const node of tree) {dfs(node, null);}return parentOfFirstChild}
9、DFS 寻找第一个叶子节点及对应的父节点
/*** 寻找第一个叶子节点及叶子节点的父节点* @param {*} tree*/findFirstChildAndParent(tree) {let firstChild = null;let parentOfFirstChild = null;const dfs = (node, parent) => {if (firstChild !== null) {return; // 如果已经找到了第一个子节点,则不再继续搜索}if (node.children && node.children.length > 0) {for (const child of node.children) {dfs(child, node);}} else {firstChild = node;parentOfFirstChild = parent;}}for (const node of tree) {dfs(node, null);}return {firstChild,parentOfFirstChild};}
相关文章:
有趣且重要的JS知识合集(22)树相关的算法
0、举例:树形结构原始数据 1、序列化树形结构 /*** 平铺序列化树形结构* param tree 树形结构* param result 转化后一维数组* returns Array<TreeNode>*/ export function flattenTree(tree, result []) {if (tree.length 0) {return result}for (const …...
使用 Let’s Encrypt 生成免费 SSL 证书
使用 Let’s Encrypt 生成证书是一个简单且免费的方式,可以通过 Certbot 工具来实现。以下是详细的步骤说明: 1. 安装 Certbot 根据你的操作系统,安装 Certbot。以下以 Ubuntu 为例: sudo apt update sudo apt install certbot…...
【电脑小白】装机从认识电脑部件开始
前言 在 B 站上刷到了一个很牛逼的电脑装机视频,很适合电脑小白学习,故用文本记录下。 推荐对组装台式电脑有兴趣的小伙伴都去看看这个视频: 原视频链接:【装机教程】全网最好的装机教程,没有之一_哔哩哔哩_bilibil…...
ssldump一键分析网络流量(KALI工具系列二十二)
目录 1、KALI LINUX 简介 2、ssldump工具简介 3、在KALI中使用ssldump 3.1 目标主机IP(win) 3.2 KALI的IP 4、操作示例 4.1 监听指定网卡 4.2 指定端口 4.3 特定主机 4.4 解码文件 4.5 显示对话摘要 4.6 显示加密数据(需要私钥&…...
使用seq2seq架构实现英译法
seq2seq介绍 模型架构: Seq2Seq(Sequence-to-Sequence)模型是一种在自然语言处理(NLP)中广泛应用的架构,其核心思想是将一个序列作为输入,并输出另一个序列。这种模型特别适用于机器翻译、聊天…...
攻防演练“轻装上阵” | 亚信安全信舱ForCloud 打造全栈防护新策略
网络世界攻防实战中,攻击风险已经从代码到云横跨全栈技术点,你准备好了吗 云服务器,攻击众矢之的 2022年超过38万个Kubernetes API服务器暴露公网,成为攻击者目标。云服务器,尤其是开源设施,一直以来不仅是…...
在Android Studio中将某个文件移出Git版本管理
最新在整理代码时发现,local.properties文件开头有这么一段注释: ## This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. 大意是这个文件不要加入到版本管理中。 之…...
Vue46-render函数
一、非单文件和单文件的main.js对比 1-1、非单文件的main.js 1-2、 单文件的main.js 将单文件的main.js中的render函数变成非单文件的main.js中的template形式,报如下错误: 解决方式: 二、解决方式 2-1、引入完成版的vue.js 精简版的vue&a…...
@RequestParam 和 @PathVariable @Param注解的区别和作用
在Spring MVC中,RequestParam、PathVariable和 RequestBody 是用于处理不同类型的请求参数的注解。每个注解都有其特定的用途和用法。让我们分别看一下它们的区别和作用。 RequestParam RequestParam用于从请求参数中获取数据,通常是处理表单数据或URL…...
复习一下。
名词解释 数字图像:数字图像是通过数字技术捕获存储和处理的图像。它由一个矩阵或二维数组的像素组成,每个像素包含图像在该位置上的颜色或亮度信息。 像素:像素是构成数字图像的最小单位。每个像素代表图像中某个位置的颜色或亮度值。 分辨…...
ripro主题如何使用memcached来加速
ripro主题是个很不错的资源付费下载主题。主题自带了缓存加速开关,只要开启了缓存加速功能,正常情况下能让网站访问的速度提升很大。 但好多人这么做了却发现没啥加速效果,原因就在于wordpress里缺少了memcache文件。只需要把object-cache.ph…...
《珊瑚岛》是一款什么类型的游戏 苹果电脑如何玩到《珊瑚岛》
在众多电子游戏中,有些游戏因其独特的游戏体验和丰富的内容而脱颖而出,《珊瑚岛》便是其中之一。在游戏中你将离开宝京前往珊瑚岛,种植农作物、饲养动物、和岛民成为朋友。您不仅可以振兴该岛小镇,还可以保护和修复周围的珊瑚礁。…...
Go - 3.库源码文件
目录 一.引言 二.库源码文件 1.定义 2.生成库源码文件 3.直接调用库源码文件 三.总结 一.引言 前面我们学习了 命令源码文件,并成功运行了 go 的 hello world 代码,下面我们介绍 go 里面另一个概念: 库源码文件。 二.库源码文件 1.定义 库源码文…...
FPGA的基础仿真项目--七段数码管设计显示学号
一、设计实验目的 1. 了解数码管显示模块的工作原理。 2. 熟悉VHDL 硬件描述语言及自顶向下的设计思想。 3. 掌握利用FPGA设计6位数码管扫描显示驱动电路的方法。 二、实验设备 1. PC机 2.Cyclone IV FPGA开发板 三、扫描原理 下图所…...
Jmeter接口请求之 :multipart/form-data 参数请求
参考教程 Jmeter压测之:multipart/form-data_jmeter form-data-CSDN博客 1、通过fiddler对接口进行抓取,接口信息如下图所示 2、获取到接口后 在fiddler右侧点击Inspectors-Raw中可以看到如下图所示信息,上半部分为默认请求头信息内容&#…...
Type-C诱骗芯片LDR6500
随着科技的飞速发展,电子设备的智能化和便携化已成为趋势。在这个过程中,Type-C接口因其高速传输、正反可插以及强大的扩展能力,逐渐成为主流接口标准。然而,Type-C接口的广泛应用也带来了一系列挑战,其中之一便是如何…...
统一异常处理
问题 当系统出现异常时,除了要在控制台、日志等后台进行输出之外,还需要在前端提示用户。 为了提示给用户,错误信息需要做一些约定: 错误信息统一用json格式返回给前端以HTTP状态码判断是否出现异常,非200即为异常 …...
Nginx网络服务
1 Nginx服务基础 Nginx( 发音为[engine x] ) 专为性能优化而开发,其最知名的优点是它的稳定性和低系 统资源消耗, 以及对HTTP 并发连接的高处理能力(单台物理服务器可支持30000~50000 个并发请求) 。正因为…...
ifconfig eth0 hw ether
ifconfig hw ether 是一个用于在 Linux 系统中设置或更改网络接口的硬件地址(即 MAC 地址)的命令。具体操作步骤如下: 首先,您需要确定要更改 MAC 地址的网络接口名称,通常是 eth0, eth1 等,取决于您的系统…...
微信小程序录音机源代码
<!-- <button bind:tap"startTab">开始录音</button> <button bind:tap"stopTab">结束录音</button> <button bind:tap"playTab">播放录音</button> <view style"margin: 0 auto;">{{ti…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 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 …...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...
Linux安全加固:从攻防视角构建系统免疫
Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...
rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...
