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());
}
}
}
}
拓扑排序-简单实现
最新推荐文章于 2021-12-03 13:36:37 发布