讲师中心 微信公众号

工具推荐

视频效率加速
Laper
Laper

剧本策划到成片协作

剧云
剧云

中文短剧剧本制作平台

Seko
Seko

AI短剧一键生成成片

AniShort
AniShort

AI短剧协同制作平台

JavaScript 深度优先排序:按嵌套层级与子节点数量递归排序树形结构

雨墨吖_2528

雨墨吖_2528

发布时间:2026-02-18 14:24:02

|

306人浏览过

|

来源于php中文网

原创

JavaScript 深度优先排序:按嵌套层级与子节点数量递归排序树形结构

本文介绍如何对具有嵌套 children 数组的树形对象数组,进行全局深度优先排序——即先按最大嵌套深度降序排列,深度相同时再按直接子节点数量降序排列,并递归应用至每一层。

本文介绍如何对具有嵌套 children 数组的树形对象数组,进行全局深度优先排序——即先按最大嵌套深度降序排列,深度相同时再按直接子节点数量降序排列,并递归应用至每一层。

在构建组织架构、菜单导航、文件目录或任务依赖图等树形数据结构时,常需按“结构复杂度”对节点排序:深层嵌套的分支往往语义上更“细化”或“具体”,应优先展示;若深度相同,则子项更多者通常更具展开价值。这种排序不能仅靠单层 sort() 实现,而需自底向上计算每个节点的最大深度(max depth),再自顶向下稳定排序并清理临时字段。

Java调试
Java调试

通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。 术语注解 JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议) remote JVM:远程 Java 虚拟机 step through code:代码单步调试(步入 / 步过 / 步出调试) inspect variables:变量查看 / 变量检视 stac

下载

核心思路:两阶段递归处理

  1. 深度标注阶段(setDepth):
    为每个节点注入 depth 属性,表示其子树的最大嵌套深度(即从该节点出发,沿任意 children 路径能到达的最远层级数)。注意:叶子节点(children: [])深度为 0;仅含空数组的节点深度为 0;有子节点的节点深度 = 1 + 子树最大深度。

  2. 排序与清理阶段(sort):
    对当前层级所有节点按 (b.depth - a.depth) 降序(深度大者靠前),深度相同时按 (b.children.length - a.children.length) 降序(子节点多者靠前);随后递归排序每个节点的 children 数组,最后删除临时 depth 字段,保持数据纯净。

完整可运行代码示例

const treeData = [{
  value: '1',
  children: [
    {
      value: '1.1',
      children: [{ value: '1.1.1', children: [] }]
    },
    {
      value: '1.2',
      children: [{
        value: '1.2.1',
        children: [
          { value: '1.2.1.1', children: [] },
          { value: '1.2.1.2', children: [] }
        ]
      }]
    },
    {
      value: '1.3',
      children: [{
        value: '1.3.1',
        children: [{
          value: '1.3.1.1',
          children: [{ value: '1.3.1.1.1', children: [] }]
        }]
      }]
    }
  ]
}];

// 步骤1:递归计算每个节点的子树最大深度
function setDepth(nodes, depth = 0) {
  if (!Array.isArray(nodes) || nodes.length === 0) return 0;

  // 为每个子节点计算其子树深度,并赋值给 child.depth
  nodes.forEach(child => {
    child.depth = setDepth(child.children);
  });

  // 当前层级最大深度 = 所有子节点 depth 的最大值 + 1(自身到子节点这一层)
  const maxChildDepth = Math.max(...nodes.map(child => child.depth), 0);
  return maxChildDepth + 1;
}

// 步骤2:递归排序(深度优先 + 同深比子量)并清理 depth 字段
function sortTree(nodes) {
  if (!Array.isArray(nodes)) return;

  // 主排序:深度降序 → 子节点数降序
  nodes.sort((a, b) => (b.depth ?? 0) - (a.depth ?? 0) || b.children.length - a.children.length);

  // 递归排序每个子节点的 children
  nodes.forEach(node => {
    sortTree(node.children);
    delete node.depth; // 清理临时字段,保持原始结构干净
  });
}

// 执行流程
setDepth(treeData);
sortTree(treeData);

console.log(JSON.stringify(treeData, null, 2));
// 输出结果中,'1.3'(深度4)排第一,'1.2'(深度3)次之,'1.1'(深度2)最后 —— 符合预期

关键注意事项

  • ✅ 深度定义明确:depth 表示“以该节点为根的子树最大层数”,非节点自身所在层级(即不计算父链)。例如 '1.3.1.1.1' 是叶子,其 depth = 0;其父节点 '1.3.1.1' 的 depth = 1。
  • ✅ 稳定性保障:排序使用 || 短路逻辑,确保深度相同时严格按 children.length 排序;递归调用保证每层独立有序。
  • ⚠️ 避免副作用:setDepth 直接修改原对象。如需不可变操作,请先深拷贝(如 structuredClone(treeData))。
  • ⚠️ 边界防护:代码已加入 Array.isArray() 和空数组判断,防止 children: undefined 或非数组值导致运行时错误。
  • ? 扩展提示:若需升序(浅层优先),将排序比较函数中的 b.depth - a.depth 改为 a.depth - b.depth 即可。

该方案时间复杂度为 O(N)(两次遍历,N 为总节点数),空间复杂度为 O(H)(递归栈深度 H),适用于中大型树形结构,是生产环境中兼顾可读性与性能的稳健实践。

热门AI工具

更多
讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

1158

2023.09.04

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2841

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

396

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

437

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

492

2026.05.09

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

6787

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2808

2023.08.10

length函数用法
length函数用法

length函数用于返回指定字符串的字符数或字节数。可以用于计算字符串的长度,以便在查询和处理字符串数据时进行操作和判断。 需要注意的是length函数计算的是字符串的字符数,而不是字节数。对于多字节字符集,一个字符可能由多个字节组成。因此,length函数在计算字符串长度时会将多字节字符作为一个字符来计算。更多关于length函数的用法,大家可以阅读本专题下面的文章。

1967

2023.09.19

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

40

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn