利用邻接矩阵实现深度优先搜索<DFS>(Java语言代码)

算法介绍:

        深度优先搜索(Depth-First Search,简称DFS)是一种用于遍历或搜索树或图的算法。它沿着图的分支尽可能深地探索,当到达某个分支的末梢时回溯,再探索下一个分支,直到所有的节点都被访问。DFS强调“深入探索”,优先探索一条路径直到无法继续,再回溯至前一节点探索其他路径。

 

 

实现原理:

  1. 定义一个DFS函数,接收三个参数:起始节点i,邻接矩阵G和标记数组visited
  2. 在主函数中,定义了一个邻接矩阵G和一个标记数组visited
  3. 调用DFS函数,传入起始节点2,邻接矩阵G和标记数组visited
  4. 在DFS函数中,首先将起始节点标记为已访问,并打印。然后,遍历邻接矩阵G中与起始节点相邻的节点,如果该节点没有被访问过且在邻接矩阵中与起始节点有连接(即G[i][j] == 1),则递归调用DFS函数。
  5. 注意:由于递归的缘故,不能将标记数组visited定义在DFS函数体内。在主函数中定义了一个标记数组,并在调用DFS函数时传入。

 

 特点:

  • 深度探索:DFS优先沿着一条路径深入,直到到达叶子节点或无法继续深入为止。
  • 栈或递归:自然适合用栈来实现(后进先出LIFO性质),也可以通过递归函数调用来实现。
  • 路径追踪:在某些应用中,DFS可以用来追踪从起始节点到当前节点的路径。
  • 循环检测:在有向图中,DFS可以用来检测环的存在。
  • 时间与空间复杂度:在无向图中,DFS的时间复杂度为O(V+E),空间复杂度在最坏情况下也是O(V+E),但若使用递归则受限于递归深度,可能会导致栈溢出。

 

应用场景:

  • 路径查找与环检测:在图中查找是否存在一条路径到达目标节点或检测图中是否有环。
  • 连通分量:确定图的连通性,找出所有强连通分量。
  • 拓扑排序辅助:虽然拓扑排序主要依赖BFS,但在某些步骤中DFS用于确定每个节点的结束时间,从而辅助进行拓扑排序。
  • 剪枝与回溯问题:DFS是解决许多回溯问题的基础,如八皇后问题、迷宫寻路等,通过剪枝减少不必要的探索。

 

实现注意事项:

  • 为了避免无限循环和重复访问,需要维护一个数据结构(如布尔数组)来记录已访问的节点。
  • 递归实现时需要注意递归深度限制,对于极深的图或树结构,可能需要考虑非递归实现方式。

 

 以下为完整程序代码(包含测试用例):

//深度优先遍历
//邻接矩阵
public class DFS_2 {
    // DFS函数
    // i 起始结点
    // G 邻接矩阵
    // visited 标记数组
    public static void dfs(int i, int[][] G, boolean[] visited) {
        System.out.print(i);// 访问初始结点i
        visited[i] = true;// 将初始结点标记为已访问
        for (int j = 0; j < G.length; j++) {
            if (visited[j] == false && G[i][j] == 1) {
                dfs(j, G, visited);// 递归
            }
        }
    }

    public static void main(String[] args) {
        int[][] G = {
                { 0, 1, 1, 0, 1 },
                { 1, 0, 0, 1, 1 },
                { 1, 0, 0, 0, 1 },
                { 0, 1, 0, 0, 1 },
                { 1, 1, 1, 1, 0 }
        };// 邻接矩阵
        boolean[] visited = new boolean[G.length];// 标记数组 注意:由于递归的缘故,不能将标记数组定义在dfs函数体内
        dfs(2, G, visited);
    }
}

 测试结果如下:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿杰_Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值