使用dfs+栈,来逆序求解拓扑序列,然后再把栈中数据逆序放到另外一个栈,实现顺序输出。
过程:
把当前点加入栈
遍历并判断当前点的邻接点
是否遍历过
是否存在栈中
如果都不是,递归及需求。
如果都是,说明存在环,return。
把当前顶点出栈。
判断环路的方法如下:
邻接点如果已经被访问了且存在于栈中,说明存在环路。
当前顶点出栈放在最后的原因:
放在最后是因为要遍历该点的所有邻接点,因为该点是他的邻接点的先决条件。
递归回退的时候,证明该点的邻接点全部访问完毕且全部合法。
package 拓扑排序;
import java.util.ArrayList;
import java.util.Stack;
//dfs求逆拓扑排序
public class dfs {
static int s[]=new int[7];
static int bz;//是否需要再继续递归
static Stack fzlist = new Stack();//复制栈
static Stack rlist = new Stack();//结果栈
static int N=4;
//无环拓扑图
/*static int map[][]={
{0,0,0,0,0},
{0,0,1,1,0},
{0,0,0,0,1},
{0,0,0,0,1},
{0,0,0,0,0}
};*/
//有环拓扑图
static int map[][]={
{0,0,0,0,0},
{0,0,1,1,0},
{0,0,0,0,1},
{0,0,0,0,1},
{0,1,0,0,0}
};
public static void main(String args[]){
dfs(1);
if(bz==0)
for (;rlist.size()>=1;) {
System.out.print(" "+rlist.pop());
}
else
System.out.println("此图有环,无解");
}
public static void dfs(int n){
s[n]=1;
fzlist.push(n);
for(int i=1;i<=N;i++)
{
if(bz==0)
{
int biaoz=0;//i点是否在fzlist栈里面的标志
for (Integer x : fzlist) {
if(x==i)biaoz=1;
}
//存在环
if(map[n][i]!=0 && s[i]==1 && biaoz==1 )
{
bz=1;
return;
}
else if(map[n][i]!=0 && s[i]!=1 && biaoz==0)//说明可以放
{
dfs(i);
}
}
else//直接返回不需要再递归了
{
return;
}
}
rlist.push(fzlist.pop());
}
}