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

[面试] js手写题-树转数组

示例数据:

const tree = [{id: 1,name: 'Root',children: [{id: 2,name: 'Child 1',children: [{ id: 4, name: 'Grandchild 1', children: [] }],},{id: 3,name: 'Child 2',children: [],},],},
]

目标生成:

const arr = [{ id: 1, name: 'Root', parentId: null },{ id: 2, name: 'Child 1', parentId: 1 },{ id: 3, name: 'Child 2', parentId: 1 },{ id: 4, name: 'Grandchild 1', parentId: 2 },
]

递归

使用递归遍历树。
在每次递归中记录当前节点的 parentId。
将节点及其子节点逐一添加到结果数组中。

时间复杂度O(n^2)

// 无parentId
function flattenTree(treeList) {let result = []// 遍历当前层级的每个节点treeList.forEach(node => {// 有子节点if (node.children) {// 递归处理子节点,获取当前节点的子节点const childList = flattenTree(node.children)delete node.children;// 将当前节点及其所有子孙节点加入结果数组result.push(node, ...childList)} else {// 没有子节点,即叶子节点result.push({ ...node})}})return result
}const flatData = flattenTree(treeData)
// 有parentId
function flattenTree(treeList, id) {let result = []// 遍历当前层级的每个节点treeList.forEach(node => {// 有子节点if (node.children) {// 递归处理子节点,获取当前节点的子节点const childList = flattenTree(node.children, node.id)delete node.children;// 将当前节点及其所有子孙节点加入结果数组result.push(node, ...childList)} else {// 没有子节点,即叶子节点result.push({ ...node, parentId: id })}})return result
}// 扁平化处理(根节点父ID设为0)
const flatData = flattenTree(treeData, null)

栈 深度优先遍历,先进后出

时间复杂度O(n)

// 栈,深度优先遍历,先进后出
function treeToArrayStack(treeList) {const stack = [...treeList]const result = []while (stack.length > 0) {//  当前节点直接pushconst node = stack.pop()result.push({ ...node })// 处理子节点if (node.children) {// 反转子节点数组以保证原始顺序stack.push(...node.children.reverse())//   删除children属性delete result[result.length - 1].children}}return result
}
// 栈,深度优先遍历,先进后出 加上parentId
function treeToArrayStack(treeList) {const stack = [];const result = []// 初始化栈(多个根节点)for (let i = treeList.length - 1; i >= 0; i--) {stack.push({ ...treeList[i], parentId: null });}while (stack.length > 0) {// 当前节点直接pushconst node = stack.pop()result.push({ ...node })// 处理子节点:反向压栈保证顺序if (node.children) {// 反转子节点数组以保证原始顺序const reversedChildren = [...node.children].reverse()reversedChildren.forEach(child => {stack.push({...child,parentId: node.id // 子节点的父ID是当前节点ID})})delete result[result.length - 1].children}}return result
}
http://www.lryc.cn/news/577232.html

相关文章:

  • 文心大模型 4.5 系列开源首发:技术深度解析与应用指南
  • uni-app使用uview2自定义tabber
  • PHP 全面解析:从入门到实践的服务器端脚本语言
  • 计算机网络中那些常见的路径搜索算法(一)——DFS、BFS、Dijkstra
  • Qt Quick 与 QML(四)qml中的Delegate系列委托组件
  • Python I/O 库 包 iopath
  • ExGeo代码理解(七)main.py(运行模型进行训练和测试)
  • 生成式人工智能实战 | 变分自编码器(Variational Auto-Encoder, VAE)
  • 如何让Excel自动帮我们算加减乘除?
  • PHP语法基础篇(七):函数
  • 电脑开机加速工具,优化启动项管理
  • 深入比较 Gin 与 Beego:Go Web 框架的两大选择
  • 深度学习04 卷积神经网络CNN
  • 国科大深度学习作业2-基于 ViT 的 CIFAR10 图像分类
  • 工业级PHP任务管理系统开发:模块化设计与性能调优实践
  • DBeaver 设置阿里云中央仓库地址的操作步骤
  • 提示技术系列——链式提示
  • 数据结构入门-图的基本概念与存储结构
  • 【软考高项论文】论信息系统项目的干系人管理
  • 利用不坑盒子的Copilot,快速排值班表
  • upload-labs靶场通关详解:第15-16关
  • docker-compose部署Nacos、Seata、MySQL
  • 《Effective Python》第十一章 性能——使用 timeit 微基准测试优化性能关键代码
  • 初始CNN(卷积神经网络)
  • C++ cstring 库解析:C 风格字符串函数
  • 深入理解Webpack的灵魂:Tapable插件架构解析
  • 人工智能和云计算对金融未来的影响
  • 大模型在急性左心衰竭预测与临床方案制定中的应用研究
  • spring-ai 工作流
  • Github 2FA(Two-Factor Authentication/两因素认证)