DFS进行逆拓扑排序

使用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<Integer> fzlist = new Stack<Integer>();//复制栈
	static Stack<Integer> rlist = new Stack<Integer>();//结果栈
	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());
	}
}

点赞