首页 > 其他分享 >逆向递归加正向递归,将无规则树 重建成一棵完整的树

逆向递归加正向递归,将无规则树 重建成一棵完整的树

时间:2022-11-19 18:11:34浏览次数:40  
标签:deptId 逆向 String 递归 List tree 无规则 path deptTree

逆向递归加正向递归,将无规则树 重建成一棵完整的树

背景 后台在一个部门树上 任意勾选,然后前端需要 知道勾选后 重新生成的树,没有父级的 找上级 依次类推。最近递归写的 很多,正向,逆向 各种 操作,(小伙伴觉得很复杂)于是我开始写这个功能,写了3个小时 集中精力。有点小累,差点没写出来。

思路 前端传 选好的 部门列表,后端 根据这些 传过来的 id,逆向递归 找到这个 部门 路径树

1,2,3 这种 拼接好,这样我们就很容易 知道每个部门的层级结构,排在前面的就是父级,

这样 前端的 部门list 就可以 知道 每个 id->path 这种 map,由于 path 里面是完整的路径,我们还需要剔除 没有 选中的 ,这样就能 构建一棵 完整的树了,遍历map,重新构建节点,根据节点构建树。

代码 如下:

public List<Tree<Long>> listDeptTreesByDataScope(List<Long> deptId) {
		Map<String,String> map = new HashMap<>();
		// 获取部门树
		List<Tree<Long>> deptTree = getDeptTree(this.list(Wrappers.emptyWrapper()), 0L);
		for (int i = 0; i < deptId.size(); i++) {
			Long id = deptId.get(i);
			String treePath = getTreePath(deptTree, id);
			// 重新构建路径
			String[] path = treePath.split(",");
			List<String> deptIds = Lists.newArrayList();
			for (int j = 0; j < path.length; j++) {
				String dId = path[j];
				if(deptId.contains(Long.valueOf(dId))){
					deptIds.add(dId);
				}
			}
			String realPath = Joiner.on(",").join(deptIds);
			map.put(String.valueOf(id),realPath);
		}
		// 重构树
		List<TreeNode<Long>> treeList = getTreeList(map,deptTree);
		if(!CollectionUtils.isEmpty(treeList)){
			List<Tree<Long>> trees = TreeUtil.build(treeList, null);
			return trees;
		}
		return Collections.emptyList();
	}
	
	private String getTreePath(List<Tree<Long>> deptTree,Long deptId){
		String path = "";
		for (int i = 0; i < deptTree.size(); i++) {
			Tree<Long> tree = deptTree.get(i);
			if(Objects.equals(tree.getId(),deptId)){
				return String.valueOf(deptId);
			}
			String treePath = buildTreePath(tree.getId(),tree.getChildren(), deptId);
			if(StringUtils.isNotBlank(treePath)){
				return treePath;
			}
		}
		return path;
	}


	private String buildTreePath(Long parentId,List<Tree<Long>> deptTree,Long deptId){
		String path = "";
		if(!CollectionUtils.isEmpty(deptTree)){
			for (int i = 0; i < deptTree.size(); i++) {
				Tree<Long> tree = deptTree.get(i);
				if(Objects.equals(tree.getId(),deptId)){
					return parentId + ","+ tree.getId();
				}
				String treePath = buildTreePath(tree.getId(), tree.getChildren(), deptId);
				if(StringUtils.isNotBlank(treePath)){
					path = parentId+","+treePath;
				}
			}
		}
		return path;
	}
	
	
	private List<TreeNode<Long>> getTreeList(Map<String,String> map,List<Tree<Long>> deptTree){
		List<TreeNode<Long>> treeList = new ArrayList<>();
		for (Map.Entry<String,String> entry:map.entrySet()){

			String value = entry.getValue();
			String[] split = value.split(",");
			if(split.length <= 1){
				TreeNode<Long> tree = new TreeNode<>();
				tree.setId(Long.valueOf(split[0]));
				tree.setParentId(null);
				tree.setWeight(Long.valueOf(split[0]));
				treeList.add(tree);
			}else {
				for (int i = 0; i < split.length-1; i++) {
					TreeNode<Long> tree = new TreeNode<>();
					tree.setId(Long.valueOf(split[i+1]));
					tree.setParentId(Long.valueOf(split[i]));
					tree.setWeight(Long.valueOf(split[i+1]));
					treeList.add(tree);
				}
			}
		}
		// 递归获取名字
		treeList.forEach( e -> e.setName(getTreeName(deptTree,e.getId())));

		return treeList;
	}

总结:有点小叼

标签:deptId,逆向,String,递归,List,tree,无规则,path,deptTree
From: https://www.cnblogs.com/lyc88/p/16906672.html

相关文章

  • 82:递归函数_阶乘计算案例
    【操作】使用递归函数计算阶乘(factorial)deffactorial(n):ifn==1:return1returnn*factorial(n-1)foriinrange(1,6):print(i,......
  • 81:递归函数_函数调用内存分析_栈帧的创建
    ###递归函数递归函数指的是:自己调用自己的函数,在函数体内部直接或间接的自己调用自己。递归类似于大家中学数学学习过的“数学归纳法”。每个递归函数必须包含两个部分:1.......
  • 337. 打家劫舍 III ----- 动态规划、递归、剪枝、分类讨论
    小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到......
  • 【iOS逆向与安全】frida-trace入门
    前言frida-trace是一个用于动态跟踪函数调用的工具。支持android和ios。安装教程请参考官网。工欲善其事必先利其器。本文将以某App为示范,演示frida-trace的各种方法在iOS......
  • 236. 二叉树的最近公共祖先 ----- 图解递归,排除左/右子树
    给定一个二叉树,找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树T的两个节点p、q,最近公共祖先表示为一个节点x,满足x是p、q......
  • Day14.1:递归
    递归理解:当A方法调用A方法,也就是方法自身调用自身。案例:定义阶乘的方法,并求出5!。publicclassDemo{publicstaticvoidmain(String[]args){System.out......
  • 方法的递归
    方法的递归,不停的调用它自己,必须写个循环条件,当满足这个循环条件时就跳出循环,跳出循环是一层一层年轮般往外跳的,这就是递归 usingSystem;namespace练习{clas......
  • 模板奇异递归+扩展方法
    #include<iostream>template<classderived>structbase{derivedgetDerivedType(){};voidinterface(){static_cast<derived*>(this)->interface();};};s......
  • [递归专题打卡]2021 6.30-7.2
    2021/6/30链接:​​https://ac.nowcoder.com/acm/problem/14310​​​ ★字符串逆序输入一个字符串,长度在100以内,按相反次序输出其中的所有字符。输入描述:输入一个字符串......
  • (二)递归 4132 四则运算表达式求值
    四则运算表达式求值​​AC代码​​​​解析​​​​坑​​​​新知识​​​​cout格式​​​​true代表1,false代表0​​​​输入流操作​​​​ASCII​​AC代码/***********......