无限层级且乱序的树形结构数据的整理,利用HashMap减少遍历次数
2014-06-09 13:57
260 查看
我们在展示一个机构树的时候,常常会遇到这样的一个问题,查询数据的时候,是从下往上查的,但展示数据的时候,又要从下往上展示。
这时候就要把查询到的数据进行整理从而得到我们想要的结构。
举个例子。
这是根据需求查询出的sql数据,但是它是无序的,所以很让人头疼,不知如何去处理,示意图是这样的。
我们先明确下数据结构吧。每一个节点我们使用一个Map存储内容,key-value映射如下。
children用来储存它的子节点的Map。
同时需要说明的是,我们的原始数据就是一个乱序的List<Map>,map中包含前三项内容。
最简单的办法就是有几层就遍历几次List。第一次遍历整个List,查找PID为0的节点,新建空的List放入Map中,这次遍历我们拿到2001这个节点,并把这个节点从List中清除。第二次遍历,查找PID为2001的节点,这次我们查到6115这个节点。依次类推,遍历四次,我们就按照层次结构形成了需要的数据。
但是这样效率不好,有没有办法能遍历一次就完成数据的整理工作呢?
看我把代码贴出来:
少了遍历,就要多添加逻辑。
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的童鞋的批评。
这时候就要把查询到的数据进行整理从而得到我们想要的结构。
举个例子。
ID | PARENT_ID | SOME_ATTRIBUTE_ID |
2001 | 0 | |
6292 | 6120 | 57010 |
6120 | 6115 | |
6121 | 6115 | |
6156 | 6121 | 56874 |
6115 | 2001 |
我们先明确下数据结构吧。每一个节点我们使用一个Map存储内容,key-value映射如下。
key | value |
ID | String |
Parent_ID | String |
Attribute_id | String |
Children | List<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的童鞋的批评。
相关文章推荐
- 无限层级且乱序的树形结构数据的整理,利用HashMap降低遍历次数
- Java编程:将具有父子关系的数据库表数据转换为树形结构,支持无限层级
- 利用多叉树将数据库中的层次数据转换成树形结构的JSON字符串
- 根据数据的父子关系创建树形结构并实现遍历
- java、js中实现无限层级的树形结构(类似递归)
- ORACLE 树形结构数据 查询某结点下全部子节点无限递归的前2个数据
- java、js中实现无限层级的树形结构(类似递归)
- java、js中实现无限层级的树形结构(类似递归)
- 根据数据的父子关系创建树形结构并实现遍历
- 根据数据的父子关系创建树形结构并实现遍历
- 数据结构 利用循环队列层次遍历一棵二叉树 递归实现
- 数据结构作业:利用中序遍历和后序遍历构建二叉树(RMQ转LCA)
- java、js中实现无限层级的树形结构方法(类似递归)
- ExtJS 4.2 树形结构请求后台数据无法展示子节点,而是没点击一次请求一次数据,无限请求加载所有的父节点元素
- 对树形结构数据进行广度优先/深度优先遍历
- 将树形结构的数据转换为二维数组 (续 PHP非递归方式实现无限分类(转载))
- 树形结构_数据库_利用递归遍历一棵只知道父节点的树
- SQL中利用递归函数取树形结构的数据
- 根据数据的父子关系创建树形结构并实现遍历
- Java、JS中实现无限层级的树形结构(类似递归)