048.图的深度优先算法原理和实现


博主的 Github 地址


1. 图的深度优先(DFS)算法的原理

1.1. 图的两种遍历策略

  • 所谓图的遍历, 就是对结点的访问.
  • 遍历图的结点, 一般有两种访问策略:
    • 深度优先遍历(Depth First Search)
    • 广度优先遍历(Board First Search)

1.2. 深度优先遍历基本思想

  • 深度优先遍历, 从初始访问结点出发, 初始访问结点可能有多个邻接结点,
    深度优先遍历的策略就是首先访问第一个邻接结点,
    然后再以这个被访问的邻接结点作为初始结点, 访问它的第一个邻接结点.

  • 可以这样理解: 每次都在访问完当前结点后首先访问当前结点的第一个邻接结点.

  • 因此这种访问策略是优先往纵向挖掘深入,
    而不是对一个结点的所有邻接结点进行横向访问.

  • 显然, 深度优先搜索是一个递归的过程.

1.3. 深度优先遍历算法步骤

  1. 访问初始结点 V, 并标记结点 V 为已访问.

  2. 查找结点 V 的第一个邻接结点 W.

  3. 若 W 存在, 则执行步骤 4;
    若 W 不存在, 则返回步骤 1, 将从 V 的下一个结点继续.

  4. 若 W 未被访问, 对 W 进行深度优先遍历递归.
    即把 W 当做另一个 V, 然后执行步骤 1/2/3.

  5. 若 W 已经被访问, 则查找结点 W 的下一个邻接结点, 转到步骤 3.

1.4. 深度优先遍历案例分析

sample
步骤:

  • 首先设置初始结点是 A, 然后开始遍历, 输出结果为: A;

  • A 的下一个邻接结点是 B, A 与 B 之间存在边, 输出结果为: A-B;

  • B 结点变为新的初始结点, 对 B 进行深度优先遍历递归,
    下一个邻接结点则为 C, B 与 C 之间存在边, 输出结果为: A-B-C;

  • C 结点成为新的初始结点, 对 C 进行递归遍历,
    下一个邻接结点为 D, 但不存在边, 因此返回上一步.

  • B 结点的下一个结点为 D, B 与 D 之间存在边, 输出结果为: A-B-C-D;

  • D 结点成为新的初始结点, 对 D 进行递归遍历,
    下一个邻接结点为 E, D 与 E 之间存在边, 输出结果为 A-B-C-D-E;

  • 至此, 全部结点输出完毕, 遍历结束.

2. 图的深度优先(DFS)算法的代码实现

  • 从上一篇中的代码中新增即可, 下面给出完整代码.

2.1. 图的邻接矩阵类

package com.leo9.dc30.graph;

import java.util.ArrayList;
import java.util.Arrays;

public class GraphMatrix {
   
   
    //定义一个 ArrayList 用来存储图中的顶点的数据集合
    private ArrayList<String> graph_vertex_list;
    //定义一个二维数组存储图对应的邻接矩阵
    private int[][] graph_edge_arr;
    //定义变量存储图中的边的数目
    private int edge_num;
    //定义数组来记录某个结点是否已被访问
    private boolean[] isVisited;

    //region 构造器, 参数是顶点数量
    public GraphMatrix(int vertex_num) {
   
   
        //初始化邻接矩阵和顶点集合, 边的数目
        //如果顶点有n个, 邻接矩阵就是n*n的矩阵
        graph_edge_arr = new int[vertex_num][vertex_num];
        //定义顶点集合的容量, 和顶点数量一致
        graph_vertex_list = new
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值