有向图的拓扑排序

什么是拓扑排序?简单地说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
若集合X上的关系R是自反的、反对称的和传递的,则称R是集合X上的偏序关系。
设R是集合X上的偏序,如果对每个x,yЄX必有xRy或yRx,则称R是集合X上的全序关系。
直观地看,偏序指集合中仅有部分成员之间可比较,而全序指集合中全体成员之间均可比较。

 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Queue;
 
 /*
  * 用来实现拓扑排序的有向无环图
  */
 public class DirectedGraph {
 
     private class Vertex{
         private String vertexLabel;// 顶点标识
         private List<Edge> adjEdges;
         private int inDegree;// 该顶点的入度
 
         public Vertex(String verTtexLabel) {
             this.vertexLabel = verTtexLabel;
             inDegree = 0;
             adjEdges = new LinkedList<Edge>();
         }
     }
 
     private class Edge {
         private Vertex endVertex;
 
         // private double weight;
         public Edge(Vertex endVertex) {
             this.endVertex = endVertex;
         }
     }
 
     private Map<String, Vertex> directedGraph;
 
     public DirectedGraph(String graphContent) {
         directedGraph = new LinkedHashMap<String, DirectedGraph.Vertex>();
         buildGraph(graphContent);
     }
 
     private void buildGraph(String graphContent) {
         String[] lines = graphContent.split("\n");
         Vertex startNode, endNode;
         String startNodeLabel, endNodeLabel;
         Edge e;
         for (int i = 0; i < lines.length; i++) {
             String[] nodesInfo = lines[i].split(",");
             startNodeLabel = nodesInfo[1];
             endNodeLabel = nodesInfo[2];
             startNode = directedGraph.get(startNodeLabel);
             if(startNode == null){
                 startNode = new Vertex(startNodeLabel);
                 directedGraph.put(startNodeLabel, startNode);
             }
             endNode = directedGraph.get(endNodeLabel);
             if(endNode == null){
                 endNode = new Vertex(endNodeLabel);
                 directedGraph.put(endNodeLabel, endNode);
             }
             
             e = new Edge(endNode);//每读入一行代表一条边
             startNode.adjEdges.add(e);//每读入一行数据,起始顶点添加一条边
             endNode.inDegree++;//每读入一行数据,终止顶点入度加1
         }
     }
 
     public void topoSort() throws Exception{
         int count = 0;
         
         Queue<Vertex> queue = new LinkedList<>();// 拓扑排序中用到的栈,也可用队列.
         //扫描所有的顶点,将入度为0的顶点入队列
         Collection<Vertex> vertexs = directedGraph.values();
         for (Vertex vertex : vertexs)
             if(vertex.inDegree == 0)
                 queue.offer(vertex);
         
         while(!queue.isEmpty()){
             Vertex v = queue.poll();
             System.out.print(v.vertexLabel + " ");
             count++;
             for (Edge e : v.adjEdges) 
                 if(--e.endVertex.inDegree == 0)
                     queue.offer(e.endVertex);
         }
         if(count != directedGraph.size())
             throw new Exception("Graph has circle");
     }
 }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值