无限层级且乱序的树形结构数据的整理,利用HashMap降低遍历次数「建议收藏」

无限层级且乱序的树形结构数据的整理,利用HashMap降低遍历次数

大家好,又见面了,我是全栈君。

我们在展示一个机构树的时候,经常会遇到这种一个问题,查询数据的时候,是从下往上查的,但展示数据的时候,又要从下往上展示。

这时候就要把查询到的数据进行整理从而得到我们想要的结构。

举个样例。

ID PARENT_ID SOME_ATTRIBUTE_ID
2001 0  
6292 6120 57010
6120 6115  
6121 6115  
6156 6121 56874
6115 2001  


这是依据需求查询出的sql数据。可是它是无序的,所以非常让人头疼,不知怎样去处理,示意图是这种。

无限层级且乱序的树形结构数据的整理,利用HashMap降低遍历次数「建议收藏」

我们先明白下数据结构吧。

每个节点我们使用一个Map存储内容,key-value映射例如以下。

key value
ID String
Parent_ID String
Attribute_id String
Children List<Map>

children用来储存它的子节点的Map。

同一时候须要说明的是,我们的原始数据就是一个乱序的List<Map>,map中包括前三项内容。

最简单的办法就是有几层就遍历几次List。第一次遍历整个List,查找PID为0的节点,新建空的List放入Map中。这次遍历我们拿到2001这个节点,并把这个节点从List中清除。

第二次遍历,查找PID为2001的节点,这次我们查到6115这个节点。依次类推。遍历四次。我们就依照层次结构形成了须要的数据。

可是这样效率不好,有没有办法能遍历一次就完毕数据的整理工作呢?

看我把代码贴出来:

<span style="white-space:pre">		</span>List<Map> list = getList();
		Map all = new HashMap();
		for(int i = 0;i<list.size();i++){
			Map result = list.get(i);
			String parent_id = (String) result.get("PARENT_ID");
			String id = (String) result.get("ID");
			if(all.get(parent_id) == null){
				Map temp = new HashMap();
				List tempList = new ArrayList();
				if(all.get(id) != null){
					((Map)all.get(id)).putAll(result);
				}else{
					result.put("children", new ArrayList());
					all.put(id, result);
				}
				tempList.add(all.get(id));
				temp.put("children", tempList);
				all.put(parent_id, temp);				
			}else{
				if(all.get(id) == null){
					result.put("children", new ArrayList());
					all.put(id, result);
				}else{
					((Map)all.get(id)).putAll(result);
				}
				((List)((Map)all.get(parent_process)).get("children")).add(result);
			}
		}

少了遍历,就要多加入逻辑。

list是我们查询的内容,我们遍历list的时候,每拿到一条。就查看在all中。是否已经存在key为parent_id的对象,假设没有,我们再看有没有key为id的对象,假设有。它一定是作为parent_id时被建立的,所以我们把其它的内容加进去,假设没有,我们就在现有的result基础上,加入key为children的list,并把它以id为key保存在all中。同一时候。再新建一个以parent_id为key的对象,当中包括children为key的List。里边包括了key为id的对象。

假设以parent_id为key的对象在all中存在。那就简单了,仅仅须要查看all中是否有以id为key的对象,有直接将其加入至parent_id为key的对象中。没有的话。建立它,再把它放进去。

逻辑上确实比較复杂,也不是非常好理解。总之我们是在all中保存了全部以不论什么一个节点为顶节点的树,仅仅须要遍历一遍,整个all中的东西都能被整理完毕。

每次做到类似的问题的时候,都非常懊悔上大学的时候对acm嗤之以鼻。

事实上如今还是有点嗤之以鼻。。。。

我认为这根本不叫算法啊。数学模型才叫算法啊。

。。。

求醍醐灌顶!

另外本文求更优的解法。尤其是学过acm的童鞋的批评。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/116201.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • cheerio获取outerHTML

    cheerio获取outerHTMLcheerio作为node中jquery的替代品,拥有与jquery相似的api,甚至连详细文档的地址都指向api.jquery.com。但是由于执行环境的关系,并没有完全继承jquery中的方法。对于这样的页面<html> <head></head> <body> <ulid=”fruits”> <li>…

    2022年6月22日
    26
  • python的常见矩阵除法_Python矩阵除法

    python的常见矩阵除法_Python矩阵除法我有一个关于按元素划分矩阵的问题,我的意思是我想要第一个矩阵的元素[I,j]除以第二个矩阵(Q)的元素[I,j]。在一些背景信息:我从我的存储器加载了一个图像。我把每个像素的单色值存储在一个叫做“pixelMatrix”的矩阵中此命令将大矩阵(128×128)转换为较小的矩阵(8×8)foto_dct=skimage.util.view_as_blocks(pixelMatrix,block…

    2022年6月14日
    165
  • linux卸载nps,Linux NPS服务部署

    linux卸载nps,Linux NPS服务部署一.安装NFS服务rpm-qa|grepnfsrpm-qa|greprpcbindyuminstallnfs-utils#如果检查的结果是没有安装,则使用该命令安装/etc/init.d/rpcbindstart/etc/init.d/nfsstart二.NFS的软件结构1.主要配置文件:/etc/exports这个档案就是NFS的主要配置文件了!…

    2022年5月2日
    217
  • 关于SM总线控制器驱动的安装

    关于SM总线控制器驱动的安装没有装SM总线控制器的再设备管理器看起来是这样的:虽然说,这个控制器不装对日常简单应用没有多大影响,但是为了保证计算机的性能,避免在使用过程中出现各种奇怪的问题,不装是不行的。下面开始安装,一般的驱动安装也可遵循此过程。首先解压ATISB600南桥驱动。我的版本是7.8的,解压默认再C:\ATI\********然后打开相应文件夹,如下图:红圈画的就是传说中的控制器驱动文件。…

    2022年6月6日
    107
  • 批处理的for循环_批处理for循环跳出循环

    批处理的for循环_批处理for循环跳出循环转自脚本之家,感谢作者与版主给我这次学习的机会基本格式(这里写的是在命令行里用的格式,如果是在批处理中,需要把其中%再多加个%形成%%):for/参数%变量in(集)do命令(注:上面除中文的以外,其余的是按它的格式要求书写的,大小写都行)参数:FOR分四种参数DLRF,并且有的参数还可附加另外的选项下面会分别介绍变量:(记住如果是在批处理中使用

    2022年10月10日
    3
  • MySQL timestampdiff()函数[通俗易懂]

    MySQL timestampdiff()函数[通俗易懂]下面说明了TIMESTAMPDIFF函数的语法。TIMESTAMPDIFF(unit,begin,end);TIMESTAMPDIFF函数返回begin-end的结果,其中begin和end是DATE或DATETIME表达式。TIMESTAMPDIFF函数允许其参数具有混合类型,例如,begin是DATE值,end可以是DATETIME值。如果使用DATE值,则TIMESTAMPDIFF函…

    2022年6月11日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号