007.求解连通分量,以及判断两个节点是否处于同一个图中

本文介绍了一种基于Java的连通分量算法实现,通过深度优先搜索(DFS)遍历图中的所有节点,确定图的连通分量数量及各连通分量的节点组成。算法使用一个整型数组记录每个节点所属的连通分量,从而快速判断任意两节点是否属于同一连通分量。
       下面的代码是基于java语言的求解连通分量的具体代码实现,其功能包含求解连通分量的个数,输出每一个连通分量的节点。判断两个节点是否处于同一个连通分量之中。
import java.util.ArrayList;

public class ConnectedComponent 
{
	private Graph G;
	private int [] visited;
	private int cccount=0;
	
	
	//构造函数
	public ConnectedComponent(Graph G)
	{
		
		this.G=G;
		visited=new int[G.V()];//设置该数组的目的是用来统计连通分量的个数
		//对于在同一次DFS遍历中所得到的遍历节点,其对应编号的数组元素赋予
		//同一个数字,比如从零开始,当DFS结束之后只需统计相同数字标记的节点
		//就可以知道某一个具体的连通分量有哪些节点
		
		for(int i=0;i<visited.length;i++)//首先将visited数组初始化
		{
			visited[i]=-1;
		}
		
		for(int v=0;v<G.V();v++)
		{
			if(visited[v]==-1)
			{
				dfs(v,cccount);//cccount作为连通分量的id传入
				cccount++;
			}
		}
	}
	//为适应求解连通分量问题而改进的dfs算法
	private void dfs(int v,int ccid)//深度优先搜索的改版
	{
		visited[v]=ccid;
		for(int w:G.adj(v))
		{
			if(visited[w]==-1)
			{
				dfs(w,ccid);
			}
		}
	}
	
	//打印不同的连通分量的具体信息
	public ArrayList<Integer>[] components()
	{
		ArrayList<Integer>[] res=new ArrayList[cccount];
		for(int i=0;i<cccount;i++)
		{
			res[i]=new ArrayList<>();
		}
		
		//基于visited数组的信息来填充res数组的内容
		for(int v=0;v<G.V();v++)
		{
			res[visited[v]].add(v);
		}
		return res;
	}
	
	
	//打印连通分量的个数以及不同连通分量的分布,注意:不同联通分量仅仅以不同的号码来区分
	public int count()
	{
		for(int e:visited)
		{
			System.out.print(e+" ");//输出各个连通分量都具有那些值
		}
		System.out.println();
		return this.cccount;
	}
	
	//判断两个节点是否连通
	public boolean isConnected(int v,int w)
	{
		G.validateVertex(v);
		G.validateVertex(w);
		return visited[w]==visited[v];
	}
	
	//测试函数
	public static void main(String[] args)//测试函数
	{
		Graph g=new Graph("g.txt");
		ConnectedComponent cc=new ConnectedComponent(g);
		//System.out.println(cc.count());
		//System.out.println(cc.isConnected(0, 6));
		//System.out.println(cc.isConnected(0, 5));
		
		ArrayList<Integer>[] comp=cc.components();
		for(int ccid=0;ccid<comp.length;ccid++)
		{
			System.out.print(ccid+":");//输出某一具体的连通分量
			for(int w:comp[ccid])
			{
				System.out.print(w+" ");
			}
			System.out.println();
		}
	}
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值