LeetCode基础-图-DFS

DFS:Depth First Search,深度优先搜索。

走迷宫的过程:

  1. 选择一条没有标记过的通道,在走过的路上铺一条绳子。
  2. 标记所有你第一次路过的路口和通道。
  3. 当到达一个标记过的路口时(用绳子)回退到上个路口。
  4. 当回退到的路口已经没有可走的通道时继续回退。
    绳子可以保证你总能找到一条出路,标记则能保证你不会两次经过同一条通道或同一个路口。

深度优先遍历的具体实现思路是:用一个递归方法遍历所有顶点,在访问其中一个顶点时:

  • 将这个顶点标记为已访问的(marked)。
  • 递归地访问这个顶点所有没有被标记过的邻接顶点。
  • 类似树的前序遍历
class DFS
{
    private bool[] marked;
    private int count;
    public DFS(Graph g, int s)
    {
        marked = new bool[g.V()];
        dfs(g, s);
    }
    private void dfs(Graph g, int v)
    {
        marked[v] = true;
        count++;
        foreach(int w in g.adj(v))
        {
            if(!marked[w])
            {
                dfs(g, w);
            }
        }
    }
    public bool marked(int w)
    {
        return marked[w];
    }
    public int count()
    {
        return count;
    }
}

DFS的图解流程:

这里写图片描述

连通性:给定一幅图,可以用 DFS 算法回答“两个给定的顶点是否连通”,“图中有多少连通子图”等问题。
单点路径:给定一幅图,给出其中一个顶点 s,是否有 顶点 s 到 顶点 v 的一条路径,如果有,找出这条路径。

路径查找:下面的代码实现了路径的查找,主要是扩展了 DFS 的代码,添加了一个变量 edgeTo[] 整型数组,作为用于搜索的绳子。这个数组可以找到每个与顶点 s 连通的顶点再回到顶点 s 的路径,可以记住每个顶点到起点的路径,而不是记录当前顶点到起点的路径。

路径查找的图解示例:

这里写图片描述

实现代码如下:

class DFSPaths
{
    private bool[] marked;//
    private int[] edgeTo; //
    private final int s; //起点
    public DFSPaths(Graph g, int s)
    {
        marked = new bool[g.V()];
        edgeTo = new int[g.V()];
        this.s = s;
        dfs(g, s);
    }
    private void dfs(Graph g, int v)
    {
        marked[v] = true;
        foreach(int w in g.adj(v))
        {
            if(!marked[w])
            {
                edgeTo[w] = v;
                dfs(g, w);
            }
        }
    }
    public bool hasPathTo(int v)
    {
        return marked[v];
    }
    public List<int> pathTo(int v)
    {
        if(!hasPathTo(v))
        {
            return null;
        }
        Stack<int> path = new Stack<int>();
        foreach(int x = v; x != s; x = edgeTo[x])
        {
            path.push(x);
        }
        path.push(s);
        return path;
    }
}

图解流程如下:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值