JAVA_链表转换为树
来源:互联网 发布:jquery weui js包下载 编辑:程序博客网 时间:2024/05/16 18:10
1)链表List中元素为Element:
a, 每个元素有一个自己的orgId;
b 指向父亲的parentOrgId;
c,孩子链表 chilren,链表中为空
详细的数据成员见文末的类Element
2) 目的: 将List中存在父节点的节点 放到它节点的孩子链表chilren中
3)收获或注意点:
a) 在list中 用foreach循环时很难在当前list中做增删,一个好的方法是使用迭代器;
b) java中非原始类型的数据 在参数传递时是引用,而非副本拷贝,所以可以在子函数中修改数据
c) 性能提升
方法1: 重复循环遍历链表List,将元素加入到它的父亲下,并在List中删除。
初始状态:第一层包含List中所有元素
结束条件:链表List中节点不再变化
时间复杂度:o( n~2) 且有递归
import java.util.ArrayList;import java.util.Iterator;import java.util.List;//将一层排列的List 转换为具有多层树形结构的Listpublic class TreeFromList {TreeFromList(){}Boolean changeList( List<Element> elist, Element element ){if(elist == null) return false;for( Element temp : elist){//如果元素父节点指向自己,会把自己删除//这句很重要if(temp.equals(element)) continue;if(element.getParentOrgId() == temp.getOrgId()){if(temp.getChildren()!=null){temp.getChildren().add(element);}else {List<Element> children = new ArrayList<Element>();children.add(element);temp.setChildren(children);}return true;}else if(temp.getChildren()!=null){//在该节点的孩子节点中查找Boolean bool=changeList(temp.getChildren(), element);if(bool) return true;}}return false;}public List<Element> convertList( List<Element> elist){if(elist == null) return null;int oldlength = elist.size();int newlength = oldlength-1;while( oldlength > newlength ){oldlength = newlength;Iterator<Element> it = elist.iterator();while(it.hasNext()){Element temp = it.next();Boolean bool=changeList( elist, temp);if(bool){System.out.println("temp =" + String.valueOf(temp.getOrgId()));it.remove();}}newlength = elist.size();}return elist;}void print(List<Element> elist ){for(Element e:elist){System.out.println("id="+String.valueOf(e.getOrgId())+ "; parentID="+String.valueOf(e.getParentOrgId()) );if(e.getChildren()!= null) {print(e.getChildren());}}}public static void main(String[] args){TreeFromList tree = new TreeFromList(); List<Element> elist = new ArrayList<Element>(); Element e1= new Element(0,0) ; elist.add(e1); Element e2= new Element(1,0) ; elist.add(e2); Element e3= new Element(2,1) ; elist.add(e3); Element e4= new Element(3,2) ; elist.add(e4); Element e5= new Element(4,2) ; elist.add(e5); Element e6= new Element(5,1) ; elist.add(e6); Element e7= new Element(6,2) ; elist.add(e7); Element e8= new Element(7,3) ; elist.add(e8); Element e9= new Element(8,1) ; elist.add(e9); Element e10= new Element(9,0) ; elist.add(e10); elist = tree.convertList(elist); System.out.println("length =" + elist.size()); tree.print(elist);}}
方法2: 在有用户交互的情况下,用户点击一个节点会在后台数据库中显示该节点的所有孩子节点
初始状态:数据放在数据库表中
获取条件:用户点击,多次查询,
优势:没用缓存,速度快
不足: 查询后台数据库较多
//直接在数据库中找孩子//方法3: 指定顶层节点为 父亲节点,每次都查表,从上往下生成树public List<Element> getOrgChildrenByOrgId( Context ctx) throws Exception{List<Element> orgListRoot=null;//数据库中获取顶层节点orgListRoot = orgService.getOrgRoot();//根据第一层获取第二层节点orgListRoot=getOrgChildren( orgListRoot);return orgListRoot;}//获取一个链表的孩子节点private List<Element> getOrgChildren( List<Element> orgListRoot) throws Exception{for(Element tempBean: orgListRoot){if(tempBean.getOrgId()==null) continue;//在数据库中获取节点的孩子children= orgService.getOrgChildrenByOrgId(tempBean.getOrgId());if(children !=null && children.isEmpty()== false){tempBean.setChildren(children);}}return orgListRoot;}
方法3: 重要思想,通过Map能够很快找到对应的元素
a ,一次性读取整个链表List,并且按照parentid排序(在非读数据库情况下可以使用快排排序)得到orderList,时间复杂度为o(nlogn)
b,根据orderList,将具有相同parentid的元素放到同一个map中得到 Map<parentid,map>, 其中子map为map<id,null>,
并使用一个类型为Map<id,elment>的mapQuery 保存所有的elment,使得根据id查询elment的查询为o(1)
总的时间复杂度为o(n)
c,在数据库中或者orderList中可以得到 顶层节点链表rootList
d,采用广度优先遍历或者深度优先遍历rootList中元素,根据parentid在Map<parentid,map>中一次直接查询到节点的所有孩子,并不断迭代
即可得到在o(n)时间复杂度内构成树
List<Element> orgCSList= new ArrayList<Element>();public List<Element> getOrgByCollectStye(Context ctx) throws Exception{//找顶层节点List<Element> orgListRoot = orgService.getOrgRoot();//顶层节点保存到orgListfor(Element ob:orgListRoot){orgCSList.add(ob);mapQuery.put(ob.getOrgId(), ob);}//找到根据父节点排序好的所有节点链表List<Element> tempOrderOrgList = orgService.getOrderOrg();//将具有相同父ID的节点放到一个map(pid, map(id,Element))Map<String, Object> tempOrderOrgMap = convertGroup(tempOrderOrgList);//生成Map树 (mapTree)和 orgListcollectToMapTree(tempOrderOrgMap, orgCSList);return orgCSList;}//第二项在第一项中收集private void collectToMapTree(Map<String, Object> tempOrderOrgMap, List<Element> orgList) throws Exception{for (Element ob:orgList ){List<Element> children = new ArrayList<Element>();Map<String,Element> obMap = (Map<String, Element>)tempOrderOrgMap.get( ob.getOrgId() ); //没有孩子if(obMap ==null || obMap.isEmpty()) {continue;}else{for(Map.Entry<String, Element> mapBean: obMap.entrySet()){children.add(mapBean.getValue());}collectToMapTree(tempOrderOrgMap, children);ob.setChildren(children);}}}Map<String, Object > convertGroup(List<Element> orgList) {if(orgList==null || orgList.isEmpty()) return null;Map<String, Object > tempMap= new HashMap<String, Object >();String pid =" ";Map<String, Element > newMap=null;for(Element ob:orgList){//在顶层Map中就不加入if(mapQuery.containsKey(ob.getOrgId()) )continue;//如果当前节点的pid与此前节点的pid不同,则是新的子Map//相等则加入前面的子map中if(pid.equalsIgnoreCase(ob.getParentOrgId() ) == false ) {//找到新的子Map,如果旧的子Map不为空,则保存if(newMap != null) tempMap.put(pid, newMap);newMap = new HashMap<String,Element>();newMap.put(ob.getOrgId(), ob);pid = ob.getParentOrgId();}else{//相等则有相同的父IDnewMap.put(ob.getOrgId(), ob);}}return tempMap;}
元素类
import java.util.List;public class Element {privateInteger orgId;private Integer parentOrgId;private List<Element> children = null;Element(Integer orgId, Integer parentOrgId){this.orgId= orgId;this.parentOrgId = parentOrgId;}public void setOrgId(Integer orgId){this.orgId =orgId;}public Integer getOrgId(){return orgId;}public void setParentOrgId(Integer parentOrgId){this.parentOrgId =parentOrgId;}public Integer getParentOrgId(){return parentOrgId;}public void setChildren(List<Element> children){this.children =children;}public List<Element> getChildren(){return children;}}
- JAVA_链表转换为树
- Java_集合操作_List转换为数组
- Java_语法基础_十进制转换为其它进制
- Java_语法基础_将字符串转换为Boolean对象
- Java_集合操作_数组转换为List
- Java_自动类型转换
- Java_强制类型转换
- java_类型转换(转)
- java_进制转换
- 二叉树转换为双向链表
- 二叉树转换为双向链表
- 二叉树转换为双向链表
- 二叉树转换为双向链表
- 二叉树转换为双向链表
- 二叉树转换为链表
- 二叉树转换为双向链表
- Java_语法基础_字节数组转换为16进制字符串
- Java_进制转换浅析;
- 第一篇
- 应用界面主题Theme使用方法
- 在社会上闯荡需要牢记的
- Jetty Struts2 Result ‘Null’ Not Found
- JSP页面禁用缓存
- JAVA_链表转换为树
- UVa 424 Integer Inquiry(整数查询)
- 写给cocos2d-x的新人,,所有疑难杂症,全都正解,包括原理,别的不用看了。(一)
- 引擎筹备
- vsftpd 服务器安装及配置
- 韩国泛泰A820L官方4.0ROM音乐播放歌曲名乱码修复记录
- UVa 299 Train Swapping(列车交换)
- C++模板学习
- 如何判断一个数是否为2的N次方