拓扑排序-简单实现

来源:互联网 发布:长沙unity3d招聘 编辑:程序博客网 时间:2024/06/03 12:41
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 ;  //顶点信息        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<Vertex, Set<Vertex>> relMap=new HashMap<>();  //顶点与节点关系        public Set<Vertex> vertices=new HashSet<>();  //所有节点信息        //添加顶点关系图        public boolean addRelVertex(Vertex start, Vertex end) {            //根据name判断重复            vertices.add(start);            vertices.add(end);            Set<Vertex> 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<Vertex> topo_sort(TopoGraph topoGraph) throws Exception {        Queue<Vertex> zeroIndegree=new LinkedList<>();        List<Vertex> resultList=new ArrayList<>();        int count = topoGraph.vertices.size() ;  //用来统计节点数,判断是否闭环        //将所有入度为0的节点入队列        for (Vertex vertex : topoGraph.vertices) {            int indegree=vertex.getIndegree();            if (indegree == 0) {                zeroIndegree.add(vertex);            }        }        //遍历队列        while (!zeroIndegree.isEmpty()) {            Vertex vertex=zeroIndegree.poll();            resultList.add(vertex);  //入结果队列            Set<Vertex> adjacents=topoGraph.relMap.get(vertex);  //相邻节点信息            if (!CollectionUtils.isEmpty(adjacents)) {                for (Vertex adj : adjacents) {                    int indegree=adj.getIndegree();                    adj.setIndegree(--indegree);                    if (0 == indegree) {    //如果入度将为0 ,则依赖节点已都出队列                        zeroIndegree.add(adj);                    }                }            }        }        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(vertexD, vertexE);        List<Vertex> result=null;        //try {            result = topo_sort(topoGraph);        //} catch (Exception e) {        //    System.out.println(e);        //}        if (result != null) {            for (Vertex vertex : result) {                System.out.println(vertex.getName());            }        }    }}