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;}}


 

原创粉丝点击