拓扑排序-简单实现

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> 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 topo_sort(TopoGraph topoGraph) throws Exception {
        Queue zeroIndegree=new LinkedList<>();
        List 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 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 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());
            }
        }

    }


}

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