java--DFS深度搜索方法

参考文章,原文链接:(5条消息) DFS(深度搜索)无向图遍历(JAVA手把手深入解析)_红目香薰的博客-CSDN博客

部分图片,代码 来自参考文章

DFS(深度搜索)方法理论与理解

节点:即图中包含数字的点,对应代码的数据

深度搜索就是:

从指定节点开始,一直向一个方向走,直到没有路

在有下一级的节点(也就是有链接的节点),我们可以向任意下级节点(没有被遍历过的)出发,还是直到没有下级,

如果没有下一级,就返回,返回到 最近的(上一个) 有未曾遍历的下级节点 的节点,

然后进入到那个未曾遍历的节点方向

输出顺序就是遍历顺序(经过顺序)

下面有手写的流程,可以参考对照,便于理解

java--DFS深度搜索方法_第1张图片
java--DFS深度搜索方法_第2张图片

DFS方法的实现

数据准备,数据输入

我们需要四个全局变量,全局变量!!!

这里的数据都是以上面的为例子

1,节点数,所有节点的记录

dian即节点(方便理解,随意命名可以),类型为需要的类型,

需要将每一个节点录入该数组,顺序可以随意(下面的二维图转换数组的顺序需要对照这个循序,所以晴考虑一下)

public static String dian[] = { "1", "2", "3", "4", "5", "6", "7" };

2、全节点数,数组长度、节点数量的记录

即所有节点的数量,

下面会按照这个长度来遍历,就是上面数组的长度,

直接定义也许, .length也许

public static int dian_length=dian.length;

3、二维数组,链接关系的记录

这个数组可以存储,每一个节点 所链接的节点都有哪些(包括上、下级);

创建的规则:

,如果有n给节点,就创建n*n的二维数组,

、第n行必须对应 节点数组 的 第n个节点

标注规则:

链接到对应的节点就标注 1

没有链接对应节点就标注 0

如果对应的节点是自身标注 0

看下面就一下明白了,,,,,.

这里用示例包含7个节点,所以7*7的二维数组

    public static int[][] arr= {
            {0,1,1,0,0,0,0},
            {1,0,0,1,1,0,0},
            {1,0,0,0,0,1,0},
            {0,1,0,0,0,0,1},
            {0,1,0,0,0,0,0},
            {0,0,1,0,0,0,0},
            {0,0,0,1,0,0,0},
    };

好像没有关系,其实很容易理解

java--DFS深度搜索方法_第3张图片

4、布尔数组,是否遍历的记录

从对方法的理解中,我们知道,再没有下级节点的时候,我们需要返回

并且继续遍历没有遍历的节点

所有我们需要记录节点是否遍历锅,

定义一个布尔类型的数组,记录所有节点的状态

将所有节点初始状态为False(因为初始的布尔数组都是False

再遍历的过程中改为true

我们就知道状态为true的节点就是遍历过的节点

public static boolean[] isfStatus;

数据处理,深度搜索

理解遇到困难可以翻到该部分最下面,有示意图

1、启动,进入递归搜索


/**                                                        
 * 开始DFS
 */                                                        
public static void DFSStart() {                            
    //初始化数组,记录使用过程                                         
    isfStatus = new boolean[dian_length];                     
    //遍历图数组                                                
    for (int i = 0; i < d_length; i++) {                   
        //因为初始的布尔数组都是false,所以只要是false就是没有走过                
        if (isfStatus[i] == false) {                       
            //进度到深度搜索的递归                                   
            DFS(i);                                        
        }                                                  
    }                                                      

实现效果,处理内容

isfStatus = new boolean[dian_length];

初始化状态记录数组,长度为dian_length,状态为false

2、

for循环,判断节点是否遍历过(状态是否为false)

是,继续循环,判断下一节点

否:执行DFS操作,并向下搜索(深度搜索)

2、深度搜索,向下搜索遍历

/**                                                       
 * 递归深搜                                                   
 * @param i                                               
 */                                                       
private static void DFS(int i) {                          
    // TODO Auto-generated method stub                    
    System.out.print(d[i] + " ");                         
    isfStatus[i] = true;                                  
    // 深度搜索子节点·从第一个节点到下一个节点                               
    for (int j = firstValue(i); j >= 0; j = nextValue(i, j)) {
        if (!isfStatus[j]) {                              
            DFS(j);                                       
        }                                                 
    }                                                     
}                                                         

firstValue() 和 nextValue() 是两个自定义函数方法,对应代码在下面,可以先看下面理解,再来看这部分

简单来说,

firstValue() 是对节点对应的数组(二维数组对应 行)遍历的值

nextValue() 是对应的下一节点的值,将要遍历的下一节点

实现效果,处理内容

1、输出当前节点

2、将当前节点的状态改为true,标记为已经遍历过的节点

3、进入当前节点再二维数组里所对应的行,寻找下一级且没有遍历过的节点,进行DFS操作

!isfStatus[j] 如果不是isfStatus[]第j个数据,isfStatus[]是布尔类型数组,所有就是判断是否遍历

3、遍历原理,firstValue() 和 nextValue()的函数部分


/**                                           
 * 第一个连接点                                     
 * @param i                                   
 * @return                                    
 */                                           
private static int firstValue(int i) {        
    for (int j = 0; j < d_length; j++) {      
        if (arr[i][j] > 0) {                  
            return j;                         
        }                                     
    }                                         
    return -1;                                
}                                             
/**                                           
 * 下一个连接点                                     
 * @param i                                   
 * @param j                                   
 * @return                                    
 */                                           
private static int nextValue(int i, int j) {  
    for (int k = (j + 1); k < d_length; k++) {
        if (arr[i][k] == 1) {                 
            return k;                         
        }                                     
    }                                         
    return -1;                                
}    
————————————————
版权声明:本文为CSDN博主「红目香薰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/feng8403000/article/details/128989010

4、结果输出


public static void main(String[] args) {
    // TODO Auto-generated method stub
    DFSStart();
}

5、示意图,助消化

java--DFS深度搜索方法_第4张图片
java--DFS深度搜索方法_第5张图片

完整代码

//我写的注释和代码太乱了,还是复制原文了

//是大佬写的有点不好理解,上面是我的理解


public class Demo_def {
    /**
     * 顶点
     */
    public static String d[] = { "1", "2", "3", "4", "5", "6", "7" };
    /**
     * 图转换数组
     */
    public static int[][] arr= {
            {0,1,1,0,0,0,0},
            {1,0,0,1,1,0,0},
            {1,0,0,0,0,1,0},
            {0,1,0,0,0,0,1},
            {0,1,0,0,0,0,0},
            {0,0,1,0,0,0,0},
            {0,0,0,1,0,0,0},
    };
    /**
     * 顶点长度
     */
    public static int d_length=d.length;
    /**
     * 记录每一个节点的遍历过程,走过则记录为true
     */
    public static boolean[] isfStatus;
    /**
     * 开始递归
     */
    public static void DFSStart() {
        //初始化数组,记录使用过程
        isfStatus = new boolean[d_length];
        //遍历图数组
        for (int i = 0; i < d_length; i++) {
            //因为初始的布尔数组都是false,所以只要是false就是没有走过
            if (isfStatus[i] == false) {
                //进度到深度搜索的递归
                DFS(i);
            }
        }
    }
    /**
     * 递归深搜
     * @param i
     */
    private static void DFS(int i) {
        // TODO Auto-generated method stub
        System.out.print(d[i] + " ");
        isfStatus[i] = true;
        // 深度搜索子节点·从第一个节点到下一个节点
        for (int j = firstValue(i); j >= 0; j = nextValue(i, j)) {
            if (!isfStatus[j]) {
                DFS(j);
            }
        }
    }
    /**
     * 第一个连接点
     * @param i
     * @return
     */
    private static int firstValue(int i) {
        for (int j = 0; j < d_length; j++) {
            if (arr[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    /**
     * 下一个连接点
     * @param i
     * @param j
     * @return
     */
    private static int nextValue(int i, int j) {
        for (int k = (j + 1); k < d_length; k++) {
            if (arr[i][k] == 1) {
                return k;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        DFSStart();
    }
 
}
————————————————
版权声明:本文为CSDN博主「红目香薰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/feng8403000/article/details/128989010

你可能感兴趣的:(java基础,深度优先,算法,数据结构,java,蓝桥杯)