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());}
- 效率问题:在每一层递归中,都需要遍历整个节点列表来查找匹配的子节点。这样的操作可能会导致性能下降,尤其是当节点列表很大时。时间复杂度为O(n^2)
- 内存消耗:递归算法需要不断地创建新的函数调用栈,每次递归调用都会占用一定的内存空间。对于大型树结构或节点列表,递归调用可能导致栈溢出或占用过多的内存。
- 重复遍历:在每一层递归中,都需要遍历整个节点列表来查找匹配的子节点。这意味着同一个节点可能会被多次遍历,导致了重复的工作。
- 综上所述,该建树算法在处理小型、非循环引用的节点列表时可能是有效的,但在处理大型、存在循环引用或需要排序的节点列表时可能存在一些缺点
优化后的建树方式
方式一
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;}
优点:
- 时间效率高:使用了HashMap来存储节点信息,通过节点的code作为key,可以快速查找到对应的节点,因此在构建树的过程中,可以快速地找到父节点并将子节点添加到父节点的children列表中,时间复杂度为O(n)。
- 空间效率高:使用了HashMap来存储节点信息,通过节点的code作为key,可以避免重复存储相同的节点,节省了存储空间。
缺点:
- 只能处理一级父子关系:该算法只能处理一级父子关系,即每个节点只能有一个直接父节点。如果存在多级父子关系,该算法无法处理。
- 需要额外的存储空间:该算法需要使用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;
}
优点:
- 时间效率高:使用HashMap作为缓存,可以快速查找和存储节点,避免了遍历查找的时间消耗,时间复杂度为O(n)。
- 空间效率高:使用HashMap作为缓存,可以避免重复构建相同的节点,减少了内存占用。
- 算法简洁易懂:通过使用HashMap的方式构建树结构,代码逻辑清晰,易于理解和维护。
缺点:
- 依赖HashMap:该算法依赖于HashMap作为缓存结构,如果数据量很大,可能会导致HashMap的内存占用过高,影响性能。
- 无法处理循环依赖:如果存在循环依赖的情况,即节点A的父节点是节点B,节点B的子节点是节点A,该算法无法处理,可能会导致死循环或树结构错误。
5w条测试数据算法耗时:
算法\次数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 平均耗时(ms) |
---|---|---|---|---|---|---|---|---|---|---|---|
getTree1 | 18 | 18 | 17 | 17 | 18 | 18 | 18 | 18 | 18 | 19 | 17.9 |
getTree2 | 15 | 14 | 15 | 15 | 14 | 15 | 15 | 15 | 14 | 16 | 14.8 |
5w条测试数据算法空间占用
算法\次数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 平均占用空间(KB) |
---|---|---|---|---|---|---|---|---|---|---|---|
getTree1 | 5853 | 4127 | 7534 | 4051 | 5052 | 5121 | 7916 | 5915 | 4127 | 6443 | 5614 |
getTree2 | 9193 | 7051 | 8096 | 12853 | 8476 | 8568 | 10983 | 11908 | 8918 | 10104 | 9615 |
相关文章:
java最优建树算法
建树算法 树的数据结构 {"code": "1111","name": "","parentcode": "0000","children": null }, {"code": "2222","name": "","parentcode": &q…...

mysql面试题30:什么是数据库连接池、应用程序和数据库建立连接的过程、为什么需要数据库连接池、你知道哪些数据库连接池
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:什么是数据库连接池? 数据库连接池是一种用于管理和复用数据库连接的技术。它是在应用程序和数据库之间建立一组数据库连接,并以池的形式存储起…...

【Vue】vscode格式刷插件Prettier以及配置项~~保姆级教程
文章目录 前言一、下载插件二、在项目内创建配置文件1.在根目录创建,src同级2.写入配置3.每个字段含义 总结 前言 vscode格式刷,有太多插件了,但是每个的使用,换行都不一样。 这里我推荐一个很多人都推荐了的Prettier 一、下载插…...

.NET 8 中的调试增强功能
作者:James Newton-King 排版:Alan Wang 开发人员喜欢 .NET 强大且用户友好的调试体验。您可以在您选择的 IDE 中设置断点,启动已经附加上调试器的程序,逐步执行代码并查看 .NET 应用程序的状态。 在 .NET 8 中,我们致…...

1310. 数三角形
知识点:(a, b)与(c, d)两点连线上点的个数为:gcd(x, y) 1(包括端点) (设横坐标差的绝对值为x, 纵坐标差的绝对值为y ) 思路:先算出选三个点的所有情况,再减去三点共线的情况 共线的斜率为0时特判 当共线…...

数据库基础(一)
数据库面试基础 注,本文章内容主要来自于JAVAGUIDE,只是结合网上资料和自己的知识缺陷进行一点补充,需要准备面试的请访问官方网址。 一、范式 参考链接 函数依赖:一张表中,确定X则必定能确定Y,则X->…...

Factory-Method
Factory-Method 动机 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具…...

【C++】神奇字符串(力扣481)
神奇字符串的规律: 神奇字符串 s 仅由 ‘1’ 和 ‘2’ 组成,并需要遵守下面的规则: 神奇字符串 s 的神奇之处在于,串联字符串中 1 和 2 的连续出现次数可以生成该字符串。 s 的前几个元素是 s “1221121221221121122……” 。如果…...
elasticsearch索引的数据类型以及别名的使用
在上篇文章写了关于elasticsearch索引的数据类型,这里就详细说下索引的增删改查以及其他的一些操作吧。 1、索引的增、删、改、查 先新建一个索引结构,代码如下 PUT test-3-2-1 {"mappings": {"properties": {"id": {&…...
分布式锁2:基于redis实现分布式锁
一 redis实现分布式锁 1.1 原理 setnxexpiredel 命令实现redis的分布式锁;其中 setnx 不存在则新增;存在则忽略。即先用setnx来抢锁,如果抢到之后,再用expire给锁设置一个过期时间,防止锁忘记了释放。例如…...

【Vue面试题十六】、Vue.observable你有了解过吗?说说看
文章底部有个人公众号:热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:Vue.observable你有了解…...

Centos7使用nginx搭建rtmp流媒体服务器
为什么写这篇文章 2023年10月份,公司系统中有个需求,需要使用摄像头记录工程师在维修设备时的工作状态,找到了一家做执法记录仪的厂商,通过厂商发过来的文档了解到该执法记录仪支持通过rtmp协议推流至服务器,第一次接…...

Springboot+vue4S店车辆管理系统(有报告),Javaee项目,springboot vue前后端分离项目。
演示视频: Springbootvue4S店车辆管理系统(有报告),Javaee项目,springboot vue前后端分离项目。 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的4S店车辆管理系统,采用M(…...

Docker与Serverless计算的集成: Docker容器如何与Serverless计算结合。
文章目录 1. Docker容器的可移植性2. Serverless计算的自动伸缩性3. 使用Serverless与Docker容器a. 自托管Serverless平台b. 使用容器服务 4. 使用案例:图像处理服务5. 结论 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉…...

Linux下kibana的安装与配置
1. 环境配置 确保Linux服务器上已安装Java 8或更高版本。可以通过运行 java -version 来验证Java的版本。 下载Kibana 7.17.11的压缩文件,可以从Kibana 7.17.11下载 上传服务器,并解压Kibana压缩文件。 2. Kibana配置 编辑Kibana的配置文件 config/k…...
LuatOS-SOC接口文档(air780E)-- http - http 客户端
示例 -- 使用http库,需要引入sysplus库, 且需要在task内使用 require "sys" require "sysplus"sys.taskInit(function()sys.wait(1000)local code,headers,body http.request("GET", "http://www.example.com/abc").wait()log.info(…...
分布式文件服务器——初识MinIO
开篇 MinIO ——开源优秀的分布式对象存储系统。 适用于AI的 高性能分布式云存储 MinIO 提供高性能、与S3 兼容的对象存储系统,让你自己能够构建自己的私有云储存服务。 MinIO原生支持 Kubernetes,它可用于每个独立的公共云、每个 Kubernetes 发行版、私…...
中国34省级行政区及行政区划代码
一、34省级行政区 23个省、4个直辖市、2个特别行政区、5个自治区。 行政区行政区划代码北京市110000天津市120000河北省130000山西省140000内蒙古自治区150000辽宁省210000吉林省220000黑龙江省230000上海市310000 江苏省320000 浙江省330000 安徽省340000 福建省…...
vue、uniapp实现组件动态切换
在Vue中,通过使用动态组件,我们可以实现组件的动态切换,从而达到页面的动态展示效果。 vue 中 component组件 is属性 功能描述 例如:有多个tabs标签,如:推荐、热点、视频等。用户点击标签就会切换到对应组…...

JVM 虚拟机面试知识脑图 初高级
导图下载地址 https://mm.edrawsoft.cn/mobile-share/index.html?uuid3f88d904374599-src&share_type1 类加载器 双亲委派模型 当一个类收到类加载请求,它首先把类加载请求交给父类(如果还有父类,继续往上递交请求).如果父类无法加载该类,再交给子类加载 防止内存中出现…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...