图的路径遍历和层级遍历

Posted 上官云霆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的路径遍历和层级遍历相关的知识,希望对你有一定的参考价值。

图的路径遍历可以得到图的所有路径图,层级遍历可以得到这个图有多少层,方便我们系统逐级加载数据
程序的主要功能

  1. 输出路径图。首选获得所有的路径图,以list展示
  2. 按层级展示(层级之间存在重复字段)。将这些路径图按层级进行归并。由于同一个字段可能以不同层级存在于一个字段,故两个层级之间存在重复字段)
  3. 按层级展示。将第二步中的字段,从高层开始向下层开始遍历,如果存在重复字段,则删除底层的重复字段。

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图的路径遍历和层级遍历

图的路径遍历和层级遍历

图的遍历广度优先遍历(DFS)深度优先遍历(BFS)及其应用

图的深度遍历和广度遍历

BFS - 20190206

GIS算法原理与开发2021-深度优先遍历