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

[面试] 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.xdnf.cn/news/14712.html

相关文章:

  • Objective-c把字符解析成字典
  • C语言常用转换函数实现原理
  • Docker 入门教程(九):容器网络与通信机制
  • React-Find 一款能快速在网页定位到源码的工具,支持React19.x/next 15
  • 【AI时代速通QT】第四节:Windows下Qt Creator调试指南
  • 【c/c++3】类和对象,vector容器,类继承和多态,systemd,stdboost
  • 「Java案例」输出24个希腊字母
  • 双指针的用法
  • Vue 3 Teleport 特性
  • 人工智能之数学基础:如何判断正定矩阵和负定矩阵?
  • 矩阵的逆 线性代数
  • LRU缓存设计与实现详解
  • Spring Cloud:服务监控与追踪的高级实践
  • C# 合并两个byte数组的几种方法
  • 零基础学习RabbitMQ(5)--工作模式(1)
  • C/C++数据结构之动态数组
  • ali PaddleNLP docker
  • vue-31(Nuxt.js 中的数据获取:asyncData和fetch)
  • XIP (eXecute In Place)
  • Spring AI Alibaba Nacos 集成实践
  • 【C++ 基础】 C++ 与 C 语言差异面试题(附大厂真题解析)
  • 【智能协同云图库】智能协同云图库第三弹:基于腾讯云 COS 对象存储—开发图片模块
  • 【Linux高级全栈开发】2.3.1 协程设计原理与汇编实现2.3.2 协程调度器实现与性能测试
  • 原型设计Axure RP网盘资源下载与安装教程共享
  • 【记录】服务器多用户共享Conda环境——Ubuntu24.04
  • 进阶向:Django入门,从零开始构建一个Web应用
  • Word之电子章制作——1
  • kubectl exec 原理
  • 力扣第73题-矩阵置零
  • Flutter基础(Children|​​Actions|Container|decoration|child)