DFS (深度优先算法)

文章目录


前言

离上次的博客已经有5天了,虽然没人关注我,但是我还是想说:我没有在偷懒,只是最近复习的知识,我觉得要自己领悟透彻才来写博客,更新不容易,能否给我点个关注。

回归正题:今天写的是DFS(深度优先)和BFS(广度优先),想必大家对这个肯定不陌生,我们在写题的时候,会遇到很多这种类型的题目,还能扩展到树与图的应用(树的DFS和BFS)。

一、DFS是什么?

DFS(深度优先搜索算法):一种用于遍历或者树或者图的算法,是一种递归程序,不断递归达到无法在到达的点,简单点来说:一条路一直走,走到没有路后就原路返回,重新选择另一条 dfs(step + 1)。

DFS = 暴搜 + 回溯算法 + 剪枝(大多数是这样)。DFS需要回溯算法,其他算法也需要回溯算法,两种是一种调用关系。

暴搜:一条路走到黑(直接递归走到底)

回溯:DFS 开启另一条路则需要回溯,如果暴搜那条路找不到答案就要回溯走另外一条道路。

剪枝:如果明确接下来的搜索找不到答案或者不是最优解,就不再进行搜索并对路径进行回溯,从而达到减少问题搜索规模的目的。

图解:(箭头的遍历方式)1 -> 2 -> 4 -> 8 -> 4 -> 2 -> 5 -> 9 - > 5 -> 2 -> 1 -> 3 -> 6 -> 10

-> 6 -> 3 -> 7。

二、DFS的使用步骤

void dfs(int step){ //step搜索的路径步骤
    判断边界问题{
        进行操作(如搜索完,并找到答案)
    }
    尝试每一种可以走的路径{
        check() return ;//剪枝
        标记该状态已经走到
        继续下一步搜索 DFS(step + 1)
        回溯(回到最开始的状态)
    }
}

三、N皇后问题

n皇后问题

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 20;
int n;
char g[N][N];    //n皇后的表格
bool col[N], dg[N], udg[N];    //状态,表示行、对角线、逆对角线放了皇后。 
void dfs(int u){    //表示第几行
    if(u == n){            //边界问题,如果u == n,说明皇后已经全部放好
        for(int i = 0; i < n; i ++) puts(g[i]);
        puts(" ");
        return ;
    }
    //n行放皇后
    for(int i = 0; i < n; i ++){
        if(!col[i] && !dg[u + i] && !udg[n - u + i]){ //如果没放皇后
            col[i] = dg[u + i] = udg[n - u + i] = true;
            g[u][i] = 'Q';
            //进行下一步
            dfs(u + 1);
            //回溯
            col[i] = dg[u + i] = udg[n - u + i] = false;
            g[u][i] = '.';
        }
    }
}

int main(){
    cin >> n;
    for(int i = 0; i < n; i ++){
        for(int j = 0; j < n; j ++){
            g[i][j] = '.';
        }
    }
	dfs(0);
	return 0;
} 


总结

这只是浅谈一下DFS,并DFS算法还有很多方面,我会在后面慢慢更新博客讲解,下一篇讲的是BFS(广度优先算法)和DFS两个都是应用与图与树的知识。

BFS的链接:         BFS(广度优先算法)_1234_6的博客-CSDN博客

  • 17
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
深度优先搜索DFS)是一种常用的遍历算法,它可以用来遍历或搜索中的节点。在DFS中,从一个起始节点开始,沿着一条路径尽可能深入地访问节点,直到无法继续深入为止,然后回溯到上一个节点,继续访问其他未被访问的节点,直到所有节点都被访问为止。 在Java中,可以使用递归或者栈来实现DFS算法。下面是一个使用递归实现DFS的示例代码: ```java import java.util.*; class Graph { private int V; // 中节点的数量 private LinkedList<Integer> adj[]; // 邻接表表示 // 构造函数 Graph(int v) { V = v; adj = new LinkedList[v]; for (int i = 0; i < v; ++i) adj[i] = new LinkedList(); } // 添加边 void addEdge(int v, int w) { adj[v].add(w); } // 递归实现DFS void DFSUtil(int v, boolean visited[]) { visited[v] = true; System.out.print(v + " "); Iterator<Integer> i = adj[v].listIterator(); while (i.hasNext()) { int n = i.next(); if (!visited[n]) DFSUtil(n, visited); } } // 对外公开的DFS接口 void DFS(int v) { boolean visited[] = new boolean[V]; DFSUtil(v, visited); } } public class Main { public static void main(String args[]) { Graph g = new Graph(4); g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(1, 2); g.addEdge(2, 0); g.addEdge(2, 3); g.addEdge(3, 3); System.out.println("节点2开始的DFS遍历结果:"); g.DFS(2); } } ``` 上述代码中,我们首先定义了一个`Graph`类来表示,其中使用邻接表来存储的结构。然后,我们实现了`DFSUtil`方法来递归地进行DFS遍历,并在遍历过中打印节点的值。最后,在`main`方法中创建一个对象,并调用`DFS`方法来进行DFS遍历。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值