无向图的几个基本算法应用

简介

    最近在看一些图相关的问题。实际上关于图相关的研究和问题已经非常多了。在前面的几篇文章里,我也谈到过图的定义、遍历法,扩展树生成和最短路径等问题。 除了这些问题及应用以外,还有一些比较常见的问题,虽然难度不大,不过经常会在一些情况下碰到。不仔细去考虑的话还是比较难解决的。这篇文章里重点要讨论解决的几个问题分别是检测图的连通性、图中间环的检测和二分图的检测。

 

图的连通性

    判断一个图的连通性,从概念上来说,就是如果一个图是连通的,那么对于图上面的任意两个节点i, j来说,它们相互之间可以通过某个路径连接到对方。比如下图:

    在这个图里,任意的两个节点都可以通过一个路径到达对方。而对于非连通的图来说,它相当于将一个图分割成多个独立的部分,每个部分之间没有任何联系,一个典型的示例如下图:

    在这个图里,7,8组成的部分以及9到12所组成的部分它们都是互相隔离的。那么如果要检查和判断一个图是否为连通的,该用什么办法呢?

 

判断图是否连通

    如果仅仅是判断一个图是否为连通的,结合前面讨论图的基础遍历方法,可以有如下的方法。在前面图遍历的方法过程中,我们是从一个指定的点开始,通过不同的策略去遍历这个图,有深度遍历和广度遍历。每次经过一个节点的时候,首先判断一下这个节点是否已经访问过了,如果没有访问过,则这个节点可以作为下一次继续遍历的候选。因为如果这个图是连通的话,这种方法最终会覆盖到整个图。所以可以采用一种计数统计的方式来实现。比如说每次访问一个以前没有遍历的节点,则将对应的计数加一。这样当最后遍历结束后,如果统计的节点和图本身的节点一样的话,表示这个图是连通的,否则表示不连通。在前面的图定义里有相关实现,这里把部分代码给转贴过来。

深度优先遍历:

public class DepthFirstSearch {
    private boolean[] marked;
    private int count;
    private final int s;

    public DepthFirstSearch(Graph g, int s) {
        marked = new boolean[g.getVertices()];
        this.s = s;
        dfs(g, s);
    }

    private void dfs(Graph g, int v) {
        marked[v] = true;
        count++;  //计数,统计访问过的节点
        for(int w : g.adj(v))
            if(!marked[w]) {
                dfs(g, w);
            }
    }

    public boolean marked(int w) {
        return hasPathTo(w);
    }

    public int count() {
        return count;
    }
}

 

广度优先遍历:

private void bfs(Graph g, int s) {
        Queue<Integer> queue = new LinkedList<I
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值