/**
* 拓扑排序:处理对象是有向图,使用的存储结构为邻接表-》每次运行的是入度为0的顶点-》使用栈进行存储
*
* @author timmy1
*
*/
public class TopologicalSort {
// 邻接表的邻接节点
class AdjoinNode {
int in;
String data;
EdgeNode firstEdge;// 第一个边节点
public AdjoinNode(int in, String data) {
super();
this.in = in;
this.data = data;
}
}
// 边的节点
class EdgeNode {
int nodeNum;// 节点的下标
EdgeNode next;// 下一个边节点
public EdgeNode(int nodeNum) {
this.nodeNum = nodeNum;
}
}
private AdjoinNode[] adjoins;
private int size;
/**
* 拓扑排序:使用栈来存储入度为零的邻接节点,然后出栈,出栈后获取到后面的边节点,边节点的入度都减去一
*/
private void topoSort() {
Stack<Integer> stack = new Stack<>();// 操作的数据为顶点的下标
for (int i = 0; i < size; i++) {
if (adjoins[i].in == 0) {
stack.push(i);
}
}
while (!stack.isEmpty()) {
// 出栈-->获取到邻接节点的下标-》获取后面的边节点-》拿到边节点的下标-》度减1
int num = stack.pop();
PrintUtil.print("到达顶点" + num);
for (EdgeNode edgeNode = adjoins[num].firstEdge; edgeNode != null; edgeNode = edgeNode.next) {
int nodeNum = edgeNode.nodeNum;// 顶点下标
int in = --adjoins[nodeNum].in;// 顶点下标的入度
if (in == 0) {
stack.push(nodeNum);
}
}
}
}
/**
* 创建图的邻接表结构
*
* @param i
*/
private void createGraphLinked(int num) {
size = num;
adjoins = new AdjoinNode[num];
AdjoinNode adjoin0 = new AdjoinNode(0, "v0");
AdjoinNode adjoin1 = new AdjoinNode(0, "v1");
AdjoinNode adjoin2 = new AdjoinNode(2, "v2");
AdjoinNode adjoin3 = new AdjoinNode(0, "v3");
AdjoinNode adjoin4 = new AdjoinNode(2, "v4");
AdjoinNode adjoin5 = new AdjoinNode(3, "v5");
AdjoinNode adjoin6 = new AdjoinNode(1, "v6");
AdjoinNode adjoin7 = new AdjoinNode(2, "v7");
AdjoinNode adjoin8 = new AdjoinNode(2, "v8");
AdjoinNode adjoin9 = new AdjoinNode(1, "v9");
AdjoinNode adjoin10 = new AdjoinNode(1, "v10");
AdjoinNode adjoin11 = new AdjoinNode(2, "v11");
AdjoinNode adjoin12 = new AdjoinNode(1, "v12");
AdjoinNode adjoin13 = new AdjoinNode(2, "v13");
adjoins[0] = adjoin0;
adjoins[1] = adjoin1;
adjoins[2] = adjoin2;
adjoins[3] = adjoin3;
adjoins[4] = adjoin4;
adjoins[5] = adjoin5;
adjoins[6] = adjoin6;
adjoins[7] = adjoin7;
adjoins[8] = adjoin8;
adjoins[9] = adjoin9;
adjoins[10] = adjoin10;
adjoins[11] = adjoin11;
adjoins[12] = adjoin12;
adjoins[13] = adjoin13;
adjoin0.firstEdge = new EdgeNode(11);
adjoin0.firstEdge.next = new EdgeNode(5);
adjoin0.firstEdge.next.next = new EdgeNode(4);
adjoin1.firstEdge = new EdgeNode(8);
adjoin1.firstEdge.next = new EdgeNode(4);
adjoin1.firstEdge.next.next = new EdgeNode(2);
adjoin2.firstEdge = new EdgeNode(9);
adjoin2.firstEdge.next = new EdgeNode(6);
adjoin2.firstEdge.next.next = new EdgeNode(5);
adjoin3.firstEdge = new EdgeNode(13);
adjoin3.firstEdge.next = new EdgeNode(2);
adjoin4.firstEdge = new EdgeNode(7);
adjoin5.firstEdge = new EdgeNode(12);
adjoin5.firstEdge.next = new EdgeNode(8);
adjoin6.firstEdge = new EdgeNode(5);
adjoin8.firstEdge = new EdgeNode(7);
adjoin9.firstEdge = new EdgeNode(11);
adjoin9.firstEdge.next = new EdgeNode(10);
adjoin10.firstEdge = new EdgeNode(13);
adjoin12.firstEdge = new EdgeNode(9);
}
public static void main(String[] args) {
TopologicalSort topologicalSort = new TopologicalSort();
topologicalSort.createGraphLinked(14);
topologicalSort.topoSort();
}
}