有趣且重要的JS知识合集(22)树相关的算法

2024-06-18 08:13

本文主要是介绍有趣且重要的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)树相关的算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1071743

相关文章

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

使用Python获取JS加载的数据的多种实现方法

《使用Python获取JS加载的数据的多种实现方法》在当今的互联网时代,网页数据的动态加载已经成为一种常见的技术手段,许多现代网站通过JavaScript(JS)动态加载内容,这使得传统的静态网页爬取... 目录引言一、动态 网页与js加载数据的原理二、python爬取JS加载数据的方法(一)分析网络请求1

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

VSCode中配置node.js的实现示例

《VSCode中配置node.js的实现示例》本文主要介绍了VSCode中配置node.js的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一.node.js下载安装教程二.配置npm三.配置环境变量四.VSCode配置五.心得一.no

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

解决tomcat启动时报Junit相关错误java.lang.ClassNotFoundException: org.junit.Test问题

《解决tomcat启动时报Junit相关错误java.lang.ClassNotFoundException:org.junit.Test问题》:本文主要介绍解决tomcat启动时报Junit相... 目录tomcat启动时报Junit相关错误Java.lang.ClassNotFoundException

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-