java最优建树算法

建树算法

树的数据结构

{"code": "1111","name": "","parentcode": "0000","children": null
},	
{"code": "2222","name": "","parentcode": "0000","children": [{"code": "1234","name": "","parentcode": "2222","children": null},{"code": "4561","name": "","parentcode": "2222","children": ["code": "7894","name": "","parentcode": "4561","children": null]}]
}

常见建树方式

    public List<TreeNodeInfo> getChildren(List<TreeNodeInfo> infos, String id) {return infos.stream().filter(g -> Objects.equals(g.getParentid(), id)).map(g -> {List<TreeNodeInfo> children = getChildren(infos, g.getId());g.setChildren(children);return g;}).collect(Collectors.toList());}
  1. 效率问题:在每一层递归中,都需要遍历整个节点列表来查找匹配的子节点。这样的操作可能会导致性能下降,尤其是当节点列表很大时。时间复杂度为O(n^2)
  2. 内存消耗:递归算法需要不断地创建新的函数调用栈,每次递归调用都会占用一定的内存空间。对于大型树结构或节点列表,递归调用可能导致栈溢出或占用过多的内存。
  3. 重复遍历:在每一层递归中,都需要遍历整个节点列表来查找匹配的子节点。这意味着同一个节点可能会被多次遍历,导致了重复的工作。
  4. 综上所述,该建树算法在处理小型、非循环引用的节点列表时可能是有效的,但在处理大型、存在循环引用或需要排序的节点列表时可能存在一些缺点

优化后的建树方式

方式一

    public List<TreeNodePO> getTree1(List<TreeNodePO> nodes) {int initialCapacity = (int) (allInfos.size() / 0.75 + 1);Map<String, TreeNodePO> map = new HashMap<>(initialCapacity);for (TreeNodePO info : nodes) {map.put(info.getCode(), info);}List<TreeNodePO> roots = new ArrayList<TreeNodePO>();String pid = null;TreeNodePOpNode = null;for (TreeNodePO node : nodes) {pid = node.getParentcode();//根节点标识if (Objects.equals(pid, "0000")) {roots.add(node);continue;}pNode = map.get(pid);if (pNode != null) {pNode.addChildren(node);}}return roots;}

优点:

  1. 时间效率高:使用了HashMap来存储节点信息,通过节点的code作为key,可以快速查找到对应的节点,因此在构建树的过程中,可以快速地找到父节点并将子节点添加到父节点的children列表中,时间复杂度为O(n)。
  2. 空间效率高:使用了HashMap来存储节点信息,通过节点的code作为key,可以避免重复存储相同的节点,节省了存储空间。

缺点:

  1. 只能处理一级父子关系:该算法只能处理一级父子关系,即每个节点只能有一个直接父节点。如果存在多级父子关系,该算法无法处理。
  2. 需要额外的存储空间:该算法需要使用HashMap来存储节点信息,需要额外的存储空间来存储节点的code和对应的节点对象,可能会占用较多的内存空间

方式二

public List<TreeNodePO> getTree2(List<TreeNodePO> allInfos) {// 创建缓存,用于存储已构建的节点int initialCapacity = (int) (allInfos.size() / 0.75 + 1);Map<String, TreeNodePO> cache = new HashMap<>(initialCapacity);//构建树List<TreeNodePO> roots = new ArrayList<>();for (TreeNodePO info : allInfos) {String code = info.getCode();String parentcode = info.getParentcode();//如果存在则get取出,不存在则put放入TreeNodePO node = cache.computeIfAbsent(code, TreeNodePO::new);node.setName(info.getName());node.setParentcode(info.getParentcode());//根节点标识if (Objects.equals(parentcode, "0000")) {roots.add(node);} else {TreeNodePO parentNode = cache.computeIfAbsent(parentcode, TreeNodePO::new);parentNode.addChildren(info);}}return roots;
}

优点:

  1. 时间效率高:使用HashMap作为缓存,可以快速查找和存储节点,避免了遍历查找的时间消耗,时间复杂度为O(n)。
  2. 空间效率高:使用HashMap作为缓存,可以避免重复构建相同的节点,减少了内存占用。
  3. 算法简洁易懂:通过使用HashMap的方式构建树结构,代码逻辑清晰,易于理解和维护。

缺点:

  1. 依赖HashMap:该算法依赖于HashMap作为缓存结构,如果数据量很大,可能会导致HashMap的内存占用过高,影响性能。
  2. 无法处理循环依赖:如果存在循环依赖的情况,即节点A的父节点是节点B,节点B的子节点是节点A,该算法无法处理,可能会导致死循环或树结构错误。

5w条测试数据算法耗时:

算法\次数12345678910平均耗时(ms)
getTree11818171718181818181917.9
getTree21514151514151515141614.8

5w条测试数据算法空间占用

算法\次数12345678910平均占用空间(KB)
getTree158534127753440515052512179165915412764435614
getTree2919370518096128538476856810983119088918101049615

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/99864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试算法19:最多删除一个字符得到回文

题目 给定一个字符串&#xff0c;请判断如果最多从字符串中删除一个字符能不能得到一个回文字符串。例如&#xff0c;如果输入字符串"abca"&#xff0c;由于删除字符’b’或’c’就能得到一个回文字符串&#xff0c;因此输出为true。 分析 本题还是从字符串的两端…

Tomcat隔离web原理和热加载热部署

Tomcat 如何打破双亲委派机制 Tomcat 的自定义类加载器 WebAppClassLoader 打破了双亲委派机制&#xff0c;它首先自己尝试去加载某个类&#xff0c;如果找不到再代理给父类加载器&#xff0c;其目的是优先加载 Web 应用自己定义的类。具体实现就是重写 ClassLoader 的两个方法…

SpringBoot全局异常处理 | Java

⭐简单说两句⭐ 作者&#xff1a;后端小知识 CSDN个人主页&#xff1a;后端小知识 &#x1f50e;GZH&#xff1a;后端小知识 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 文章目录 ✨SpringBoot全局异常处理 | Java&#x1f3a8;什么是全局…

CAXA汇总尺寸避免混乱

把单图的尺寸名称全部重命名

Android 13 骁龙相机点击拍照流程分析(二)——点击拍照到存入相册

一.前言 本篇是在Android 13 骁龙相机点击拍照流程分析(一)——点击拍照到更新到左下角缩略图文章的基础上进行延申的,前面的预览、点击拍照的过程参考第一篇:Android 13 骁龙相机点击拍照流程分析(一)——点击拍照到更新到左下角缩略图-CSDN博客 二.生成图片并保存 从第…

KUKA机器人通过直接输入法设定负载数据和附加负载数据的具体操作

KUKA机器人通过直接输入法设定负载数据和附加负载数据的具体操作 设置背景色: 工具负载数据 工具负载的定义: 工具负载数据是指所有装在机器人法兰上的负载。它是另外装在机器人上并由机器人一起移动的质量。需要输入的值有质量、重心位置、质量转动惯量以及所属的主惯性轴。…

爱尔眼科角膜塑形镜验配超百万,全力做好“角塑镜把关人”

你知道吗?过去的2022年&#xff0c;我国儿童青少年总体近视率为53.6%&#xff0c;其中6岁儿童为14.5%&#xff0c;小学生为36%&#xff0c;初中生为71.6%&#xff0c;高中生为81%①。儿童青少年眼健康问题俨然成为全社会关心的热点与痛点&#xff0c;牵动着每一个人的神经。 好…

给手机上液冷?谈谈华为Mate 60系列手机专属黑科技—— “微泵液冷”手机壳

最近&#xff0c;有一个手机配件吸引了我的注意——华为的微泵液冷壳。 简单来说&#xff0c;就是在手机壳里装了无线充电微泵&#xff0c;为手机实现外置水冷的能力。让手机壳在“外观装饰”和“防摔保护”的功能性上额外加了一个“降温提性能”的作用。 接下来&#xff0c;本…

深度学习DAY3:神经网络训练常见算法概述

梯度下降法&#xff08;Gradient Descent&#xff09;&#xff1a; 这是最常见的神经网络训练方法之一。它通过计算损失函数对权重的梯度&#xff0c;并沿着梯度的反方向更新权重&#xff0c;从而逐步减小损失函数的值。梯度下降有多个变种&#xff0c;包括随机梯度下降&#…

软考-高级系统架构师复习知识点总结

软件架构概念 软件架构定义 系统的一个或多个结构。结构中包含软件的构件、构件的外部可见属性、构件之间的相互关系。 软件架构设计与生命周期 需求分析阶段:问题空间,根据需求模型构件SA模型、保证模型转换的可追踪性 设计阶段 SA模型的描述: SA的基本概念:构件、…

MySQL之MHA集群

MHA概述 什么是 MHA MHA&#xff08;MasterHigh Availability&#xff09;是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。 MHA 的出现就是解决MySQL 单点故障的问题。 MySQL故障切换过程中&#xff0c;MHA能做到0-30秒内自动完成故障切换操作。 MHA能在故障切换…

iPhone手机上使用的定时提醒APP是哪个

在日常喧闹的生活和工作中&#xff0c;琐碎的任务会像喷泉一样突涌而至&#xff0c;如不及时规划&#xff0c;我们将陷入手足无措的境地。而想要让各项工作任务按时完成&#xff0c;我们可以借助一些比较好用的时间提醒软件来督促各项任务。 就拿常用的iPhone手机来讲&#xf…

Flutter的Platform介绍-跨平台开发,如何根据不同平台创建不同UI和行为

文章目录 Flutter跨平台概念介绍跨平台开发平台相关性Platform ChannelPlatform-specific UIPlatform Widgets 如何判断当前是什么平台实例 Platform 类介绍获取当前平台的名称检查当前平台其他属性 利用flutter设计跨Android和IOS平台应用的技巧1. 遵循平台的设计准则2. 使用平…

回归算法全解析!一文读懂机器学习中的回归模型

目录 一、引言回归问题的重要性文章目的和结构概览 二、回归基础什么是回归问题例子&#xff1a; 回归与分类的区别例子&#xff1a; 回归问题的应用场景例子&#xff1a; 三、常见回归算法3.1 线性回归数学原理代码实现输出例子&#xff1a; 3.2 多项式回归数学原理代码实现输…

Ubuntu磁盘满了,导致黑屏

前言 &#xff08;1&#xff09;最近要玩Milk-V Duo&#xff0c;配置环境过程中&#xff0c;发现磁盘小了。于是退出虚拟机&#xff0c;扩大Ubuntu大小&#xff0c;重新开机&#xff0c;发现无法进入Ubuntu界面。 &#xff08;2&#xff09;查了很久&#xff0c;后面发现是磁盘…

javascript二维数组(19)不要键名只保留值的算法

在数组var a[ {pre1_day_off:1}, {pre2_day_off:2}, {pre3_day_off:3} ]中&#xff0c;如果去除键名只保留值&#xff0c;形成[1,2,3]这样的数组格式 在JavaScript中&#xff0c;你可以通过使用Array.prototype.map函数来实现这个目标。map函数遍历数组的每个元素&#xff0c;然…

这短短 6 行代码你能数出几个bug?

前言&#xff1a;本文仅仅只是分享笔者一年前见到的诡异代码&#xff0c;大家可以看看乐子&#xff0c;随便数一数一共有多少个bug&#xff0c;这数bug多少还是要点水平的 在初学编程的时候&#xff0c;写的第一个代码大多都是 hello world&#xff0c;可是就算是 hello world…

Windows安装Node.js

1、Node.js介绍 ①、Node.js简介 Node.js是一个开源的、跨平台的JavaScript运行环境&#xff0c;它允许开发者使用JavaScript语言来构建高性能的网络应用程序和服务器端应用。Node.js的核心特点包括&#xff1a; 1. 事件驱动: Node.js采用了事件驱动的编程模型&#xff0c;通…

04训练——基于YOLO V8的自定义数据集训练——在windows环境下使用pycharm做训练-1总体步骤

在上文中,笔者介绍了使用google公司提供的免费GPU资源colab来对大量的自定义数据集进行模型训练。该方法虽然简单好用,但是存在以下几方面的短板问题: 一是需要通过虚拟服务器做为跳板机来访问,总体操作起来非常繁杂。 二是需要将大量的数据上传缓慢,管理和使用非常不友…

FutureTask和CompletableFuture的模拟使用

模拟了查询耗时操作&#xff0c;并使用FutureTask和CompletableFuture分别获取计算结果&#xff0c;统计执行时长 package org.alllearn.futurtask;import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; import lombok.AllArgsConstructor; imp…