public class Graph {
/**
* 节点数量
*/
public int v;
public LinkedList<Integer> adj[];
private Graph(int v) {
this.v = v;
// 初始化顶点
adj = new LinkedList[v];
for (int i = 0; i < v; i++) {
adj[i] = new LinkedList<>();
}
}
/**
* 添加边
* @param i
* @param j
*/
private void addEdge(int i, int j) {
adj[i].add(j);
}
}
public class TopoSort {
/**
*
* @param graph
*/
private static void topoSort(Graph graph, int v) {
// 辅助作用
LinkedList<Integer> queue = new LinkedList<>();
int[] result = new int[v];
// 每个节点的入度
int[] degree = new int[v];
for (int i = 0; i < v; i++) {
for (int j = 0; j < graph.adj[i].size(); j++) {
int w = graph.adj[i].get(j);
degree[w]++;
}
}
// 把入度为0的加入队列中
for (int i = 0; i < v; i++) {
if (degree[i] == 0) {
queue.add(degree[i]);
break;
}
}
// 开始逐个处理
int currentIndex = 0;
while (!queue.isEmpty()) {
int node = queue.remove();
result[currentIndex++] = node;
// 获取此节点的出边
LinkedList<Integer> edges = graph.adj[node];
for (int j = 0; j < edges.size(); j++) {
int w = edges.get(j);
degree[w]--;
if (degree[w] == 0) {
queue.add(degree[w]);
}
}
}
}
private static void topoSortByDFS(Graph graph, int v) {
// 首先简历逆序表
LinkedList<Integer>[] reseveEdges = new LinkedList[v];
// 初始化
for (int i = 0; i < v; i++) {
reseveEdges[i] = new LinkedList<>();
}
for (int i = 0; i < v; i++) {
for (int j = 0; j < graph.adj[i].size(); j++) {
int w = graph.adj[i].get(j);
reseveEdges[w].add(i);
}
}
// 逆序表简历完成,创建节点的访问情况
boolean[] visible = new boolean[v];
for (int i = 0; i < v; i++) {
// 逐个节点进行遍历
if (!visible[i]) {
visible[i] = true;
travelDFS(i, reseveEdges, visible);
}
}
}
private static void travelDFS(int v, LinkedList<Integer>[] reseveEdges, boolean[] visit) {
// 访问的时候先访问入度的节点,再访问自身
LinkedList<Integer> lastNodes = reseveEdges[v];
for (int i = 0; i < lastNodes.size(); i++) {
int w = lastNodes.get(i);
if (visit[w]) {
continue;
}
// 否则访问夫节点
travelDFS(w, reseveEdges, visit);
}
Log.d("zpb", "-->" + v);
}
}