前言
前几天正好看到一个题目是求一张有向无环图所有可能的拓扑排序
(拓扑排序定义见拓扑排序,其核心在于在拓扑排序中,任意结点需要排在他所有的前置结点后面。)之前想着手写试试看,后面发现可能的排序太多了,于是开始研究可不可以用代码来实现。
代码实现
其实本身并不是很复杂,直接上代码吧
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ListAll {
private static final List<List<Integer>> RESULT = new ArrayList<>();
private static final int[][] EDGES = {
{},
{2, 3, 4},
{7},
{5, 6},
{6},
{8},
{8, 9},
{10},
{10},
{10},
{}
};
private static final List<Integer> NEXT = new ArrayList<>();
public static void topologicalSort(List<Integer> oneResult, int[] inDegree, List<Integer> next) {
if (next.size() > 0) {
for (int i = 0; i < next.size(); i++) {
List<Integer> tempNext = new ArrayList<>(next);
List<Integer> tempOneResult = new ArrayList<>(oneResult);
tempNext.remove(next.get(i));
tempOneResult.add(next.get(i));
int[] tempInDegree = Arrays.copyOf(inDegree, inDegree.length);
int[] tempEdges = EDGES[next.get(i)];
for (int tempEdge : tempEdges) {
tempInDegree[tempEdge]--;
if (tempInDegree[tempEdge] == 0) {
tempNext.add(tempEdge);
}
}
topologicalSort(tempOneResult, tempInDegree, tempNext);
}
} else {
RESULT.add(oneResult);
}
}
public static void main(String[] args) {
//邻接表元素个变化,inDegree初始长度也变化
int[] inDegree = new int[11];
Arrays.fill(inDegree, 0);
for (int i = 1; i < EDGES.length; i++) {
for (int j = 0; j < EDGES[i].length; j++) {
inDegree[EDGES[i][j]]++;
}
}
for (int i = 1; i < inDegree.length; i++) {
if (inDegree[i] == 0) {
NEXT.add(i);
}
}
topologicalSort(new ArrayList<>(), inDegree, NEXT);
System.out.println("result size="+RESULT.size());
for (List<Integer> integers : RESULT) {
for (Integer integer : integers) {
System.out.print(integer + " ");
}
System.out.println();
}
}
}
其中EDGES是初始化构造所有可以走的点(为了方便索引0就没用),result用来存储所有可能的结果,next用来表示当前所有还可以走的点,运行结果如下,一共是336种情况(所以原题用的是“写出”还是蛮夸张的,这真的是可以写得完的么)