拓扑排序-bfs-广度优先搜索

package com.ygy.test.sort;

import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Created by guoyao on 2017/10/11.
 */

//拓扑排序
public class TopologicalSorting {

    //定义顶点信息
    private static class Vertex {

        @Getter @Setter
        private  int indegree;  //入度

        @Getter @Setter
        private String name ;  //顶点信息

        //广度优先搜索新增字段
        @Getter @Setter
        private int deepPath = Integer.MIN_VALUE ;  //路径深度 初始化为最小

        @Getter @Setter
        private Boolean isKnown = false ;   //路口是否已探  初始化为false

        @Getter @Setter
        private Vertex preShortVertex ;

        public boolean isKnown() {
            return isKnown ;
        }

        public Vertex(String name) {
            this.name=name;
            indegree = 0 ;   //初始入度为0
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Vertex vertex=(Vertex) o;

            return name.equals(vertex.name);
        }

        @Override
        public int hashCode() {
            return name.hashCode();
        }
    }

    //定义拓扑关系图
    private static class TopoGraph {

        public Map> relMap=new HashMap<>();  //顶点与节点关系

        public Set vertices=new HashSet<>();  //所有节点信息

        //添加顶点关系图
        public boolean addRelVertex(Vertex start, Vertex end) {

            //根据name判断重复
            vertices.add(start);
            vertices.add(end);

            Set adjcents=relMap.get(start);  //相邻节点信息
            if (CollectionUtils.isEmpty(adjcents)) {
                adjcents = new HashSet<>();
            }

            if (adjcents.contains(end)) {
                return false;
            }

            adjcents.add(end);
            int indegree=end.getIndegree();
            end.setIndegree(++indegree);    //入度+1
            relMap.put(start, adjcents);
            return true;
        }
    }

    public static List bfs_sort(TopoGraph topoGraph, Vertex firstRoot) {
        Queue knownQueue=new LinkedList<>();
        List resultList=new ArrayList<>();
        firstRoot.setDeepPath(0);  //设置深度为0
        firstRoot.setIsKnown(true);  //设置为已探知
        knownQueue.add(firstRoot);
        while (!knownQueue.isEmpty()) {

            Vertex knownVertex=knownQueue.poll();
            resultList.add(knownVertex);
            Set adjacents=topoGraph.relMap.get(knownVertex);  //相邻节点信息

            if (!CollectionUtils.isEmpty(adjacents)) {
                for (Vertex adj : adjacents) {
                    if (!adj.isKnown()) {
                        //深度+1 表明为已探知,指定上一个节点
                        adj.setDeepPath(knownVertex.getDeepPath() + 1);
                        adj.setIsKnown(true);
                        adj.setPreShortVertex(knownVertex);
                        knownQueue.add(adj);
                    }
                }
            }
        }
        return resultList;
    }

    public static void printShortPath(List list) {

        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (Vertex vertex : list) {
            int count = 0 ;
            while (vertex != null) {
                if (count != 0) {
                    System.out.print("<----");
                }
                System.out.print(vertex.getName()+ ":"+ vertex.getDeepPath());
                vertex = vertex.preShortVertex;
                count ++ ;
            }
            System.out.println();
        }
    }

        if (count != resultList.size()) {
            throw new RuntimeException(" 闭环");
        }
        return resultList;

    }


    public static void main(String[] args) throws Exception  {

        Vertex vertexA=new Vertex("A");
        Vertex vertexB=new Vertex("B");
        Vertex vertexC=new Vertex("C");
        Vertex vertexD=new Vertex("D");
        Vertex vertexE=new Vertex("E");
        TopoGraph topoGraph=new TopoGraph();
        topoGraph.addRelVertex(vertexA, vertexB);
        topoGraph.addRelVertex(vertexA, vertexC);
        topoGraph.addRelVertex(vertexC, vertexD);
        topoGraph.addRelVertex(vertexB, vertexD);
        topoGraph.addRelVertex(vertexB, vertexE);
        topoGraph.addRelVertex(vertexD, vertexE);

        //广度优先搜索
        List vertices=bfs_sort(topoGraph, vertexA);
        printShortPath(vertices);        
    }
    //打印结果   到达 a b c d e 的最短路径
         //A:0
        //B:1<----A:0
        //C:1<----A:0
        //D:2<----B:1<----A:0
        //E:2<----B:1<----A:0

}

你可能感兴趣的:(java数据结构)