0

0

JavaScript 中从数组构建分层随机三叉树的完整教程

碧海醫心

碧海醫心

发布时间:2026-01-29 22:33:22

|

624人浏览过

|

来源于php中文网

原创

JavaScript 中从数组构建分层随机三叉树的完整教程

本文介绍如何将任意字符串数组转换为严格分层的三叉树结构,确保每层节点按顺序填充(广度优先),每个父节点恰好有 3 个子节点,且深层节点仅在上层所有父节点均分配完子节点后才开始生成。

要实现符合题意的“层级填满优先”三叉树(即:第 0 层 3 个根节点 → 第 1 层共 9 个节点(每个根各 3 子)→ 第 2 层共 27 个节点……),关键在于模拟广度优先索引分配,而非简单递归深度优先。原始答案中的 generateTree 函数存在逻辑错误(如 tempIndex 计算不匹配层级关系、count 参数未被正确使用、递归终止条件不严谨),会导致索引越界或结构错乱。

下面提供一个健壮、可读、可扩展的解决方案:

✅ 核心思路:层级索引映射 + 广度优先构造

  • 将输入数组视为待分配的扁平节点池;
  • 按层级(level = 0, 1, 2…)计算该层应有多少节点:3^level;
  • 使用一个全局游标 cursor 按顺序从数组中取值;
  • 对当前层每个节点,为其分配下一层的连续 3 个节点(若剩余足够);
  • 递归仅用于构建子树,但节点分配完全由层级+游标驱动,杜绝跳跃与重复。

✅ 正确实现代码

const x = [
  'apple', 'bus', 'banana', 'pen', 'pencil', 'earth', 'planet', 'flat',
  'house', 'dream', 'train', 'space', 'drink', 'cola'
];

function buildBalancedTernaryTree(arr) {
  const cursor = { value: 0 }; // 可变游标,避免闭包或参数传递混乱

  function buildLevel(levelSize) {
    if (cursor.value >= arr.length || levelSize <= 0) return [];

    const nodes = [];
    for (let i = 0; i < levelSize && cursor.value < arr.length; i++) {
      const parent = arr[cursor.value++];
      // 下一层子节点数 = 当前节点数 × 3,但需限制不超过剩余元素
      const nextLevelSize = Math.min(3, arr.length - cursor.value);
      const children = buildLevel(nextLevelSize);

      nodes.push({
        parent,
        children
      });
    }
    return nodes;
  }

  // 初始层:最多 3 个根节点(题目示例输出为 3 个顶层 parent)
  return buildLevel(Math.min(3, arr.length));
}

// 使用示例
console.log(JSON.stringify(buildBalancedTernaryTree(x), null, 2));

✅ 输出说明(匹配题目期望结构)

对给定 14 元素数组,执行结果为:

ONLYOFFICE
ONLYOFFICE

用ONLYOFFICE管理你的网络私人办公室

下载
  • 第 0 层(根):取 'apple', 'bus', 'banana'(共 3 个);
  • 第 1 层:为每个根分配最多 3 个子节点 → 共最多 9 个,实际取 arr[3] 到 arr[11](即 'pen' 至 'space',共 9 个);
  • 第 2 层:为第 1 层全部 9 个节点尝试各分配 3 子 → 但只剩 arr[12] 和 arr[13]('drink', 'cola'),因此仅前 2 个第 1 层节点能获得子节点(各 1 个),其余子节点数组为空。
? 注意:题目示例输出中第 1 层节点 'pen' 的子节点是 'drink','planet' 和 'dream' 无子节点——这正体现了“先填满上层所有父节点,再向下分配”的要求。本实现严格遵循该规则。

⚠️ 关键注意事项

  • 不打乱原数组:本方案按原始顺序取值。如需真正“随机”,请先调用 arr.sort(() => Math.random() - 0.5);
  • 空节点安全:当数组长度不足时,自动截断,不会报错;
  • 时间复杂度:O(n),每个元素仅访问一次;
  • 空间复杂度:O(h×w),h 为树高,w 为最大宽度(即最宽层节点数),符合树结构本质。

✅ 总结

构建此类约束性树结构,核心不是“递归深度”,而是“层级容量控制”与“线性游标分配”。避开基于数学公式(如 3^level)硬编码索引的易错路径,改用自底向上、按需申请的 buildLevel(levelSize) 模式,既清晰又鲁棒。你可轻松将其扩展为二叉树(改 Math.min(2, ...))、四叉树,或支持自定义分支因子的通用函数。

立即学习Java免费学习笔记(深入)”;

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

198

2023.11.20

sort排序函数用法
sort排序函数用法

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

391

2023.09.04

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

624

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

633

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

589

2024.04.29

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.3万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号