图的路径遍历和层级遍历
Posted 上官云霆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的路径遍历和层级遍历相关的知识,希望对你有一定的参考价值。
图的路径遍历可以得到图的所有路径图,层级遍历可以得到这个图有多少层,方便我们系统逐级加载数据
程序的主要功能
- 输出路径图。首选获得所有的路径图,以list展示
- 按层级展示(层级之间存在重复字段)。将这些路径图按层级进行归并。由于同一个字段可能以不同层级存在于一个字段,故两个层级之间存在重复字段)
- 按层级展示。将第二步中的字段,从高层开始向下层开始遍历,如果存在重复字段,则删除底层的重复字段。
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 节点
*/
@Setter
@Getter
@ToString
public class Node
/**
* 唯一标识
*/
private String id;
// 其他字段自行补充
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* 边
*/
@Setter
@Getter
@ToString
public class Edge
/**
* 起点
*/
private Node start;
/**
* 结束
*/
private Node end;
import java.util.*;
/**
* 识别有向图中的所有路径
*/
public class Graph
/**
* 所有路径图
*/
private List<List<Node>> allWay = new ArrayList<>();
/**
* 通过线构建图
*
* @param edgeList
*/
public Graph(List<Edge> edgeList)
Map<Node, Set<Node>> map = new HashMap<>();
Set<Node> startSet = new HashSet<>();
Set<Node> startSetBack = new HashSet<>();
Set<Node> endSet = new HashSet<>();
edgeList.stream().forEach(flowData ->
startSet.add(flowData.getStart());
startSetBack.add(flowData.getStart());
endSet.add(flowData.getEnd());
if (map.containsKey(flowData.getStart()))
Set<Node> elementSet = map.get(flowData.getStart());
elementSet.add(flowData.getEnd());
else
Set<Node> elementSet = new HashSet<>(1);
elementSet.add(flowData.getEnd());
map.put(flowData.getStart(), elementSet);
);
// 获取起点和终点,构建路径图
startSet.removeAll(endSet);
endSet.removeAll(startSetBack);
startSet.forEach(start ->
endSet.forEach(end ->
buildWay(start, end, map, new ArrayList<>());
);
);
private void buildWay(Node start, Node end, Map<Node, Set<Node>> relationMap, List<Node> way)
if (relationMap.containsKey(start))
// 获取下一个节点
Set<Node> elementSet = relationMap.get(start);
for (Node element : elementSet)
// 如果节点是终点则直接返回,否则继续递归查询
if (element.equals(end))
LinkedList<Node> newWay = new LinkedList<>(way);
newWay.add(start);
newWay.add(end);
allWay.add(newWay);
else
List<Node> newWay = new ArrayList<>(way);
newWay.add(start);
buildWay(element, end, relationMap, newWay);
@Override
public String toString()
Map<Integer, Set<String>> nodeLevelMap = new HashMap<>();
int index = 0;
for (List<Node> linkedList : allWay)
System.out.println("=========== list ==============");
for (Node element : linkedList)
System.out.println(element.toString());
Set<String> tmpNodeSet = null;
if (nodeLevelMap.get(index) != null)
tmpNodeSet = nodeLevelMap.get(index);
else
tmpNodeSet = new LinkedHashSet<>();
tmpNodeSet.add(element.getId());
nodeLevelMap.put(index, tmpNodeSet);
index++;
index = 0;
Iterator<Map.Entry<Integer, Set<String>>> entries = nodeLevelMap.entrySet().iterator();
while (entries.hasNext())
Map.Entry<Integer, Set<String>> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
// TODO 从最大深度开始处理
int maxLevel = nodeLevelMap.size() - 1;
for (int i = maxLevel; i > 1; i--)
Set<String> beginSet = nodeLevelMap.get(i);
for (int j = i - 1; j > 0; j--)
Set<String> compareSet = nodeLevelMap.get(j);
compareSet.removeAll(beginSet);
nodeLevelMap.remove(j);
nodeLevelMap.put(j, compareSet);
System.out.println("第二次遍历");
Iterator<Map.Entry<Integer, Set<String>>> entries2 = nodeLevelMap.entrySet().iterator();
while (entries2.hasNext())
Map.Entry<Integer, Set<String>> entry2 = entries2.next();
System.out.println("Key = " + entry2.getKey() + ", Value = " + entry2.getValue());
return "";
public Map<Integer, Set<String>> toNodeLevelMap()
Map<Integer, Set<String>> nodeLevelMap = new HashMap<>();
int index = 0;
System.out.println("---------输出路径图--开始-------");
for (List<Node> linkedList : allWay)
System.out.println("=========== list ==============");
for (Node element : linkedList)
System.out.println(element.toString());
Set<String> tmpNodeSet = null;
if (nodeLevelMap.get(index) != null)
tmpNodeSet = nodeLevelMap.get(index);
else
tmpNodeSet = new LinkedHashSet<>();
tmpNodeSet.add(element.getId());
nodeLevelMap.put(index, tmpNodeSet);
index++;
index = 0;
System.out.println("---------输出路径图--结束-------");
int maxLevel = nodeLevelMap.size() - 1;
// 【set 排序】 -从小到大排序(可加可不加,按实际需求处理)
for (int i = 0; i <= maxLevel; i++)
Set<String> tmpSet = nodeLevelMap.get(i);
Set<String> sortSet = new TreeSet<String>((o1, o2) -> Long.valueOf(o1).compareTo(Long.valueOf(o2)));
sortSet.addAll(tmpSet);
nodeLevelMap.put(i, sortSet);
System.out.println("---------第一次遍历----按层级展示(层级之间存在重复字段)--开始---");
Iterator<Map.Entry<Integer, Set<String>>> entries = nodeLevelMap.entrySet().iterator();
while (entries.hasNext())
Map.Entry<Integer, Set<String>> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
System.out.println("---------第一次遍历--结束-------");
// 从最大深度开始处理 --将 底层与高层重复的元素进行删除
for (int i = maxLevel; i > 1; i--)
Set<String> beginSet = nodeLevelMap.get(i);
for (int j = i - 1; j > 0; j--)
Set<String> compareSet = nodeLevelMap.get(j);
compareSet.removeAll(beginSet);
nodeLevelMap.remove(j);
nodeLevelMap.put(j, compareSet);
System.out.println("---------第二次遍历----按层级展示--开始---");
Iterator<Map.Entry<Integer, Set<String>>> entries2 = nodeLevelMap.entrySet().iterator();
while (entries2.hasNext())
Map.Entry<Integer, Set<String>> entry2 = entries2.next();
System.out.println("Key = " + entry2.getKey() + ", Value = " + entry2.getValue());
System.out.println("---------第二次遍历--结束-------");
return nodeLevelMap;
import java.util.Arrays;
/**
* 主函数 --适用于图的遍历 和 层级遍历
* 图的遍历可以得到图的所有路径图
* 层级遍历可以得到这个图有多少层,方便我们系统逐级加载数据
* 1. 输出路径图。首选获得所有的路径图,以list展示
* 2. 按层级展示(层级之间存在重复字段)。将这些路径图按层级进行归并。由于同一个字段可能以不同层级存在于一个字段,故两个层级之间存在重复字段)
* 3. 按层级展示。将第二步中的字段,从高层开始向下层开始遍历,如果存在重复字段,则删除底层的重复字段。
*/
public class Main
public static void main(String[] args)
// 构建图的节点
Node e1 = new Node();
e1.setId("1");
Node e2 = new Node();
e2.setId("2");
Node e3 = new Node();
e3.setId("3");
Node e4 = new Node();
e4.setId("4");
Node e5 = new Node();
e5.setId("5");
Node e6 = new Node();
e6.setId("6");
Node e7 = new Node();
e7.setId("7");
// 构建图的边
Edge f1 = new Edge();
f1.setStart(e1);
f1.setEnd(e2);
Edge f2 = new Edge();
f2.setStart(e1);
f2.setEnd(e3);
Edge f3 = new Edge();
f3.setStart(e2);
f3.setEnd(e4);
Edge f4 = new Edge();
f4.setStart以上是关于图的路径遍历和层级遍历的主要内容,如果未能解决你的问题,请参考以下文章