拓扑排序的实现

1.知识储备
在这里插入图片描述
在这里插入图片描述
2.检测有向图中的环:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码:

package Graph;

public class DirectedCycle {
    //索引代表顶点,值表示当前顶点是否已经被搜索
	private boolean[] marked ;
	//记录图中是否有环
	private boolean hasCycle;
	//索引代表顶点,使用栈的思想,记录当前顶点有没有已经处于正在搜索的有向路径上
	private boolean[] onStack;
	//创建一个检测环对象,检测图中G是否有环
	public DirectedCycle(DiGraph G) {
		// TODO Auto-generated constructor stub
		//初始化marked数组
		this.marked=new boolean[G.V()];
		//初始化hasCycle
		this.hasCycle=false;
		//初始化onStack数组
		this.onStack=new boolean[G.V()];
		//找到图中每一个顶点,让每一个顶点作为入口,调用一次dfs搜索
		for(int v=0;v<G.V();v++){
			//判断如果当前顶点还没有搜索过,则调用dfs进行搜索
			if(!marked[v]){
				dfs(G,v);
			}
		}
	}
	
	//基于深度优先搜索,检测图G中是否有环
	private void dfs(DiGraph G,int v){
		//把顶点v标识为也搜索
		marked[v]=true;
		//把当前顶点进栈
		onStack[v]=true;
		//进行深度搜索
		for(Integer w:G.adj(v)){
			//判断如果当前顶点还没有被搜索过,则继续递归调用dfs方法完成深度优先搜索
			if(!marked[w]){
				dfs(G,w);
			}
			//判断当前顶点w是否已经在栈中,如果已经在栈中,说明当前顶点正处于搜索状态,那么现在又要搜索一次,就证明已经检测到环了
			if(onStack[w]){
				hasCycle=true;
				 return ;
			}
		}
		//把当前顶点出栈
		onStack[v]=false;
	}
	
	//判断当前图G中是否有环
	public boolean hasCycle(){
		return hasCycle;
	}
}

3.顶点排序:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码:

package Graph;

import Stack.Stack;

public class DepthFirstOrder {
    //索引代表顶点,值表示当前顶点是否已经被搜索
	private boolean[] marked;
	//使用栈,存储顶点序列
	private Stack<Integer> reverserPost;
	
	//创建一个检测环对象,检测图G中是否有环
	public DepthFirstOrder(DiGraph G){
		//初始化marked数组
		this.marked=new boolean[G.V()];
		//初始化reverse栈
		this.reverserPost=new Stack<Integer>();
		//遍历图中的每一个顶点,让每个顶点作为入口,完成一次深度优先搜索
		for(int v=0;v<G.V();v++){
			if(!marked[v]){
				dfs(G,v);
			}
		}
	}
	
	//基于深度优先搜索,把顶点排序
	public void dfs(DiGraph G,int v){
		//标记v已经被搜索
		marked[v]=true;
		//通过循环深度搜索顶点v
		for(Integer w: G.adj(v)){
			//如果当前顶点w没有被搜索,则继续调用dfs递归搜索
		if(!marked[w]){
			dfs(G,w);
		  }
		}
		//让顶点v进栈
		reverserPost.push(v);
	}
	
	//获取顶点线性序列
	public Stack<Integer> reversePost(){
		
		return reverserPost;
	}
}

4.拓扑排序的实现:
在这里插入图片描述代码实现:

package Graph;

import Stack.Stack;

public class ToPoLogical {
     //顶点的拓扑排序
	private Stack<Integer> order;
	
	//构造拓扑排序对象
	public ToPoLogical(DiGraph G) {
		// TODO Auto-generated constructor stub
		//创建一个检测有向环的对象
		DirectedCycle cycle=new DirectedCycle(G);
		//判断G图中有没有环,如果没有环,则进行顶点排序,创建一个顶点排序对象
		if(!cycle.hasCycle()){
			DepthFirstOrder depthfirstorder= new DepthFirstOrder(G);
			order=depthfirstorder.reversePost();
		}
	}
	//判断图G是否有环
	private boolean isCycle(){
		return order==null;
	}
	
	//获取拓扑排序的所有顶点
	public Stack<Integer>  order(){
		return order;
	}
}

测试类:

package Graph;

import Stack.Stack;

public class TopoLogicalTest {
    public static void main(String[] args) {
		//准备有向图
    	DiGraph diGraph =new DiGraph(6);
    	diGraph.addEdge(0,2);
    	diGraph.addEdge(0,3);
    	diGraph.addEdge(2,4);
    	diGraph.addEdge(3,4);
    	diGraph.addEdge(4,5);
    	diGraph.addEdge(1,3);
    	//通过ToPoLogical对象对有向图的顶点进行排序
    	ToPoLogical topological=new ToPoLogical(diGraph);
    	//获取顶点的线性序列进行打印
    	Stack<Integer> order=topological.order();
    	StringBuilder sb=new StringBuilder();
    	for(Integer w: order){
    		sb.append(w+"->");
    		
    	}
    	String str 	=sb.toString();
    	int index=str.lastIndexOf("->");
    	str=str.substring(0,index);
    	System.out.println(str);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值