【拓扑排序】代码实现

参考文章
读完本文你将能够完成t207课程表,t210课程表II
【拓扑排序】代码实现_第1张图片

int[][] prerequisites = [[0,2],[1,2],[2,3],[2,4]];//有向图prerequisites有5个顶点,[0,2]代表结点0指着结点2
int n = 5;//代表5个顶点
int[][] g = new int[n][n];//邻接表g有5个表头结点,每个表头结点最多4个边表结点,g[2][3] = 1 代表结点2有个边表结点是结点3
int[] indeg = new int[n];//入度数组indeg,indeg[4]=1代表节点4的入度等于1
int[] res = new int[n];//拓扑排序序列答案res数组

//遍历图 填充各记录数组
for(int i = 0; i < prerequisites.length; i++){
	int a = prerequisites[i][0];//i=0 a=0 b=2
	int b = prerequisites[i][1];
	g[a][b] = 1;//g[0][2] = 1 代表 表头结点0的边表结点是有结点2的
	indeg[b] += 1;//结点2的入度加一
}

LinkedList<Integer> queue = new LinkedList<>();//存放度为0的结点
//要拓扑排序 先找入度为0的结点 一次性将入度为0的点全部入队
for(int i = 0; i < indeg.length; i++){
	if(indeg[i] == 0)	queue.offer(i);
}

int index = 0;//遍历res数组用的指针,也可以当做统计当前拓扑序列res的图结点个数
//...以下代码类似树的层次遍历迭代法
//遍历入度为0的结点t,添加进res,在遍历过程中发现入度为0的结点就入队
while(!queue.isEmpty()){
	int t = queue.poll();//删除入度为0的结点t,
	res[index++] = t;//添加进res序列,
	
	//把结点t在邻接表上的边表结点们的入度都减一
	for(int i = 0; i < g[t].length; i++){
		//如果g[t][i]=1 代表结点t存在边表结点i
		if(g[t][i] == 1){
			indeg[i] -= 1;//边表结点i入度减一
			if(indeg[i] == 0)
				queue.offer(i);//如果边表结点i入度减一后,入度变成了0,就要入队
		}
	}
}

if(index == n)		
	System.out.println("拓扑排序序列包含全部结点,即存在拓扑排序,图里不存在环");
else	
	System.out.println("拓扑排序序列不包含全部结点,即不存在拓扑排序,图里存在环");

你可能感兴趣的:(Java,笔记,刷题)