树形结构的遍历过程全遍历

news/2024/7/8 12:49:01

前言

树形结构是项目开发中常常用到的一种结构,也是一种经典的数据结构,比如说常见的二叉树,红黑树等,今天要说的不是基础的数据结构,是业务中用到的树形数据结构。

正文

先来看看业务是什么吧!

业务

在这里插入图片描述
如这张图,上图中的每一个节点都是可以独立发送消息的,而其消息内容就是节点中的条件1和条件2并且加上其所有的祖籍节点的条件信息。怎样遍历整颗树呢?我是通过三层for循环实现的。

实现

先看从数据库中查出的数组的详细情况:
在这里插入图片描述
数组中总共有6条数据,每条数据中有当前节点的id对应上图中的serialNumber 和当前节点的父节点pid 对应上图中的hierarchy ,通过遍历这个数组来实现业务中的需求。

代码
private StringBuffer processGraphString(String processGraphId){
        StringBuffer stringBuffer=new StringBuffer();
        //微服务间调用,查询同一流程画布下的所有的策略器
        ItooResult processData= iProcessGraph.queryProcessGraph(processGraphId);
        HashMap processMap=(HashMap) processData.getData();
        //取出查出的策略器数组
        List policyList=(List) processMap.get("policyrRelevanceModelList");
        //定义一个新的数组,此数组是最终的一个数组,里边存放策略器数组,存放当前策略器id及当前策略器的所有祖籍策略器id
        List listAll=new ArrayList();
        if (policyList !=null){
            //策略器组合的数组
            String temp="";
            for (int i = 0; i <policyList.size() ; i++) {
                //拿到单个的策略器对象
                HashMap policyHashMap=(HashMap) policyList.get(i);
                //取出当前策略器对象中的父id
                String policyFather=(String) policyHashMap.get("hierarchy");

                if (temp.equals("")){
                    //此树结构中总根节点不在循环遍历的过程中当程序第一次运行时中间变量temp为空,temp存储的是当前策略器的父节点id
                    temp=policyFather;
                    //在树的列表中查找出当前策略器节点的所有子节点集合
                    //policyList 中存储的是一个完整的树结构的数组,也就是总的数组
                    //policyFather 中存储的是当前策略器的父节点id
                    List listChild = ergodicList(policyList, policyFather, policyList);
                    listAll.addAll(listChild);
                }else if (!temp.equals(policyFather)) {
                    List listChild = ergodicList(policyList, policyFather, policyList);
                    listAll.addAll(listChild);
                }
                temp=policyFather;
            }
        }
        //循环遍历listAll中的所有策略器id并根据id查询字符串
        if (listAll.size()!=0){
            for (int i = 0; i < listAll.size(); i++) {
                List list=(List) listAll.get(i);
                for (int j = 0; j < list.size(); j++) {
                    HashMap hashMap=(HashMap) list.get(j);
                    String policyId=(String)hashMap.get("policyCanId");
                    stringBuffer.append(policyString(policyId));
                }
            }
        }
        return stringBuffer;
    }
    /*
    * 功能描述:遍历数组得到新的数组
    * [childList]
    * @return
    */
    private List ergodicList(List childList,String rootNode,List fatherList){
        //childList,fatherList是整个完整的树形结构数组
        //rootNode是父节点id,每次的值是变化的

        //新建的listChild作用待定
        //List listChild=new ArrayList();
        //要返回的数组,就是传入的rootNode节点的所有的子节点数组
        List returnList=new ArrayList();
        //循环整个完整的树形结构的数组
        for (int i = 0; i <childList.size() ; i++) {
            //定义一个新的数组,数组中存的是当前根节点是rootNod节点的所有父节点的策略器和当前的策略器
            List newList=new ArrayList();

            HashMap processHash=(HashMap)childList.get(i);
            //获取当前策略器的hierarchy编号作为父项编号
            String hierarchyNum=(String) processHash.get("hierarchy");
            //hierachyNum是否与根节点相同如果相同说明 hierarchyNum是根节点的一个子节点,将这个子节点插入到新的数组中
            if (rootNode.equals(hierarchyNum)){
                //listChild.add(processHash);
                //当前策略器本身
                newList.add(processHash);
                //当前策略器的父节点策略器
                //hierarchyNum是当前的策略器的父节点
                List list= ergodic(fatherList,hierarchyNum);

                newList.addAll(list);
            }
            if (newList.size() != 0){
                returnList.add(newList);
            }
        }
        return returnList;
    }

    /**
    * 功能描述:通过叶子节点找到当前分支上的所有的父节点并存储到一个list
    * [fatherList, hierarchyNum]
    * @return 当前叶子节点所在分支上的所有父节点
    */
    private List ergodic(List fatherList,String hierarchyNum){
        //fatherList 是整个树的全部list集合
        List newList=new ArrayList();
        //将根节点赋值给中间变量temp
        String temp=hierarchyNum;
        //循环整体的全部list集合
        for (int j = 0; j < fatherList.size(); j++) {
            //获取当前策略器
            HashMap processHashFather=(HashMap)fatherList.get(j);
            //获取当前策略器的serialNumber作为比对条件,进行条件的拼接
            String serialFatherA=(String) processHashFather.get("serialNumber");
            //获取当前策略器的hierarchy编号作为父项编号
            String hierarchyNumA=(String) processHashFather.get("hierarchy");
            if (hierarchyNum.equals(serialFatherA)){
                newList.add(processHashFather);
                temp=hierarchyNumA;
            }
            //让此方法循环找到同一条线上的所有父节点
            if (!temp.equals("0") && (j==fatherList.size()-1)){
                j=-1;
                hierarchyNum=temp;
            }
        }
        return newList;
    }

针对于三个for循环的说明:
第一个for循环主要是遍历当前树中的所有的节点。
第二个for循环主要是根据父节点信息找到这个父节点的所有的子节点,并且找到子节点的所有祖籍节点。
第三个for循环整个树,根据当前节点id找到所有的祖籍节点。

当然这个种方法不管是时间复杂的还是空间复杂度都很高。

结束

针对于以上的树形结构遍历的问题,还有其他的设计方案来解决。
在树形结构的维护表中添加一个维护字段,字段的内容为当前节点的所有的祖籍节点。
通过祖籍节点可以得到所有想要的整棵树的信息,而其也比较简单。


http://www.niftyadmin.cn/n/1974365.html

相关文章

2014-11-6Android学习------Android图像处理之Bitmap类

Bitmap是Android系统中的图像处理的最重要类之一。用它可以获取图像文件信息&#xff0c;进行图像剪切、旋转、缩放等操作&#xff0c;并可以指定格式保存图像文件。本文从应用的角度&#xff0c;着重介绍怎么用Bitmap来实现这些功能。 一、Bitmap的生成 1.1 BitmapFactory dec…

Android如何绘制视图,解释了为何onMeasure有时要调用多次

2019独角兽企业重金招聘Python工程师标准>>> 原文地址&#xff1a;How Android Draws Views 当Activity获取焦点的时候&#xff0c;它就需要绘制布局。Android框架会处理绘制过程&#xff0c;但这个Activity必须提供它布局树的根节点。 绘制过程是从布局的根节点开始…

安利一个画图的网站

前言 大家画流程图&#xff0c;架构图都用什么呢&#xff1f;之前画图用的不同的软件安装到电脑上&#xff0c;比如微软的Visio 画甘特图各种图也都能画&#xff0c;但是不免费不香。然后有用了ProcessOn这个也是挺好用的&#xff0c;就是免费的图有点少&#xff0c;后来通过多…

2014-11-6Android学习------Android Paint和Color类、Canvas类的常用属性

要绘图&#xff0c;首先得调整画笔&#xff0c;待画笔调整好之后&#xff0c;再将图像绘制到画布上&#xff0c;这样才可以显示在手机屏幕上。 graphics中包括了Canvas&#xff08;画布&#xff09;、Paint&#xff08;画笔&#xff09;、Color&#xff08;颜色&#xff09;、B…

14.4.9 Innodb通用表空间

2019独角兽企业重金招聘Python工程师标准>>> 一. 通用表空间简介 通用表空间是innodb表空间新类型&#xff0c;5.7.6引入 通用表空间提供以下功能&#xff1a; 类似系统表空间&#xff0c;是共享表空间&#xff0c;能存储多个表的数据相比独立表空间&#xff0c;通用…

前端时间格式的转换

前言 有没有遇到过写前端页面渲染数据的时候发现后端接口给的格式不能直接拿过来渲染&#xff0c;这个时候怎么办呢&#xff1f;找写接口的小伙伴探讨一下&#xff0c;让他改接口&#xff0c;当然是一种办法&#xff0c;但是作为一个团队就是不管前端给我什么我都能渲染成我想…

2014-11-6Android学习------Android画笔实现画曲线--------贝塞尔曲线(二)

写一篇文章很辛苦啊&#xff01;&#xff01;&#xff01; 转载请注明&#xff0c;联系请邮件nlp30508qq.com 我学习Android都是结合源代码去学习&#xff0c;这样比较直观&#xff0c;非常清楚的看清效果&#xff0c;觉得很好&#xff0c;今天的学习源码是网上找的源码 百度搜…

7.MongoDB java CRUD

注意&#xff1a;要增加mongodb对应的jar包 package cn.toto.mongodb; import java.net.UnknownHostException; import org.bson.types.ObjectId; import org.junit.Test; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; …