递归获取拉平存储的树每个节点到达的路径
2016-11-12 00:00
447 查看
最近公司的一个项目需要把存储在数据库中树结构拉出来,并且要计算到达每个节点的路径。下午想了一下实现,周一要交差,抽出关键代码:
输出结果:
/** * Copyright © 2016 my. All rights reserved. */ package cn.mycompay.mysystem; import static java.text.MessageFormat.format; import java.util.List; import org.apache.commons.lang3.StringUtils; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Strings.emptyToNull; import static com.google.common.base.Joiner.on; import static com.google.common.collect.Lists.reverse; /** * 获取到达树每个节点的路径 * * @author James 2016年11月12日 下午4:14:58 * */ public class TreePath { /** * 根据平铺树计算路径 * * @param nodes */ private static void genPath(List<Node> nodes) { for (Node node : nodes) { List<String> path = newArrayList(); recurNode(nodes, node, node, path); } } /** * 递归查找父节点 * * @param nodes * 所有节点 * @param targetNode * 目标节点 * @param currentNode * 当前节点 * @param path * 路径 */ private static void recurNode(List<Node> nodes, Node targetNode, Node currentNode, List<String> path) { if (StringUtils.equals(currentNode.getNodeNo(), currentNode.getParentNodeNo())) { throw new RuntimeException(format("非法的树结构,node:{0}", currentNode.getNodeNo())); } path.add(checkNotNull(emptyToNull(currentNode.getNodeCode()), format("节点编码为空,node:{0}", currentNode.getNodeNo()))); // 终止条件,这里约定null,""表示根节点 if (StringUtils.isBlank(currentNode.getParentNodeNo())) { targetNode.setPath(on(".").join(reverse(path))); return; } // 节点编号必须唯一,每次只能找到一个父节点 for (Node node : nodes) { if (StringUtils.equals(currentNode.getParentNodeNo(), node.getNodeNo())) { recurNode(nodes, targetNode, node, path); return; } } // 既不是根节点又无法找到父节点 throw new RuntimeException(format("非法的树结构,node:{0}", currentNode.getNodeNo())); } /** * @param args */ public static void main(String[] args) { List<Node> tree = newArrayList(); // 第一颗课树 tree.add(new Node("1", "A", "")); tree.add(new Node("2", "B", "1")); tree.add(new Node("3", "C", "2")); tree.add(new Node("4", "D", "3")); tree.add(new Node("5", "E", "1")); tree.add(new Node("6", "F", "2")); // 第二课树 tree.add(new Node("11", "AA", "")); tree.add(new Node("22", "BB", "11")); tree.add(new Node("33", "CC", "22")); tree.add(new Node("44", "DD", "33")); tree.add(new Node("55", "EE", "11")); tree.add(new Node("66", "FF", "22")); tree.add(new Node("77", "GG", "66")); genPath(tree); for (Node node : tree) { System.out.println(node.getPath()); } } } /** * 平铺的树 对应数据库中一条记录 * * @author James 2016年11月12日 下午4:15:26 * */ class Node { public Node(String nodeNo, String nodeCode, String parentNodeNo) { super(); this.nodeNo = nodeNo; this.nodeCode = nodeCode; this.parentNodeNo = parentNodeNo; } /** * 节点唯一编号 */ private String nodeNo; /** * 节点编码 */ private String nodeCode; /** * 父节点编码 */ private String parentNodeNo; /** * 根据元数据递归生成到达节点路径 */ private String path; /** * @return the nodeNo */ public String getNodeNo() { return nodeNo; } /** * @param nodeNo * the nodeNo to set */ public void setNodeNo(String nodeNo) { this.nodeNo = nodeNo; } /** * @return the nodeCode */ public String getNodeCode() { return nodeCode; } /** * @param nodeCode * the nodeCode to set */ public void setNodeCode(String nodeCode) { this.nodeCode = nodeCode; } /** * @return the parentNodeNo */ public String getParentNodeNo() { return parentNodeNo; } /** * @param parentNodeNo * the parentNodeNo to set */ public void setParentNodeNo(String parentNodeNo) { this.parentNodeNo = parentNodeNo; } /** * @return the path */ public String getPath() { return path; } /** * @param path * the path to set */ public void setPath(String path) { this.path = path; } }
输出结果:
A A.B A.B.C A.B.C.D A.E A.B.F AA AA.BB AA.BB.CC AA.BB.CC.DD AA.EE AA.BB.FF AA.BB.FF.GG
相关文章推荐
- Treeview中,递归生成从当前选中节点到根节点的全路径
- 通用获取父节点/子节点/子节点下所有节点ID的存储过程
- Android获取多存储路径
- java 递归获取一个目录下的所有文件路径
- [DevExpress]获取TreeListNode选中节点全部路径信息
- xml获取指定节点的路径
- android获取相机默认存储路径的最后一张照片
- TreeView根据节点获取完整路径
- php递归无限级分类【先序遍历算】,获取任意节点下所有子孩子
- 对一个存储学生信息的单向链表,按照学号升序对链表进行排序,每个节点包含了一个学生ID
- 获取CAD中线的每个节点坐标程序设计(一)
- 根据路径名获取目录节点
- 无向图的一节点到另一节点的最短路径(边数最少的路径)(采用邻接表存储)
- 获取数据库存储路径 sql server
- Xml 根据路径和属性值获取节点
- 递归获取当前节点的父节点
- C# 递归TreeView 与根据选择的节点获得整个节点路径
- lua lfs库的使用——递归获取子文件路径
- php递归无限级分类【先序遍历算】,获取任意节点下所有子孩子
- android获取外部存储和内部存储路径