【2】深度优先算法详解

1 引言

深度优先算法(Depth-First Search,DFS)与广度优先算法(BFS)已经有很多介绍了,深度优先算法(DFS)是一种用于遍历或搜索树或图的算法。这个算法会尽可能深地搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问过为止。

顾名思义,与广度优先算法不同,深度优先算法对树进行搜索时,不会遍历当前层级的所有节点,而是每次往下深入一层,直到搜索到当前树的最底层。

2 深度优先算法图解

如图1所示,8个节点组成了3条路径,节点0为起点,节点7为终点,现通过此图对DFS进行讲解。

第1步:将节点0加入当前搜索列表,即此时当前搜索列表为[0],已搜索列表为空[].

第2步:查找节点0的邻接节点,此处节点0有两个邻接节点(节点1和节点2),根据DFS规则,我们按先后顺序先只搜索第一个 邻接节点即节点1,将节点0加入已搜索节点,同时将节点0从搜索列表删除,将节点1加入搜索列表,即此时当前搜索列表为[1],已搜索列表为[0].

 第三步,查找节点1的邻接节点,此处节点1有1个邻接节点(节点3),将节点1加入已搜索节点,同时将节点1从搜索列表删除,将节点3加入搜索列表,即此时当前搜索列表为[3],已搜索列表为[0, 1].

第4步:查找节点3的邻接节点,此处节点3有两个邻接节点(节点5和节点6),根据DFS规则,我们按先后顺序先只搜索第一个 邻接节点即节点5,将节点3加入已搜索节点,同时将节点3从搜索列表删除,将节点5加入搜索列表,即此时当前搜索列表为[5],已搜索列表为[0, 1, 3].

 第5步:查找节点5的邻接节点,发现节点5无邻接节点,执行节点回溯,将节点5从搜索列表删除,将已搜索列表中的最后一个节点(节点3)加入搜索列表,同时将节点5加入已搜索列表,即此时当前搜索列表为[3],已搜索列表为[0, 1, 5].

第6步:查找节点3的邻接节点,此处节点3有两个邻接节点(节点5和节点6),节点5在已搜索列表中,我们按先后顺序搜索第二个邻接节点即节点6,将节点3加入已搜索节点,同时将节点3从搜索列表删除,将节点6加入搜索列表,即此时当前搜索列表为[6],已搜索列表为[0, 1,  5, 3].

第7步,查找节点6的邻接节点,节点6有一个邻接节点即节点7,已找到终点,搜索结束。

3 Matlab算例

以邻接矩阵为算例,进行DFS算法验证,给出一个6*6邻接矩阵:

Map = [0 1 0 0 0 0;

0 0 1 1 0 0;

0 0 0 0 0 0;

0 0 0 0 1 0;

0 0 0 0 0 1;

0 0 0 0 0 0];

完整代码如下:

 clc;close all;clear
% 使用邻接矩阵表示图  
Map = [0 1 0 0 0 0; 
    0 0 1 1 0 0; 
    0 0 0 0 0 0; 
    0 0 0 0 1 0; 
    0 0 0 0 0 1; 
    0 0 0 0 0 0];  
  
% 队列
queue = 1;% 当前节点之前的搜寻队列(用于节点回溯)

Num = length(Map(:, 1));
visited = false(1, Num);% 已访问标志
% 从第一个节点开始深度优先搜索
node = 1;
nodepre = DFS(visited, Map, queue, node);


%% 函数定义
function nodepre = DFS(visited, Map, queue, node)
nodepre = zeros(length(Map(:, 1)), 1);
Map_Temp = Map;
% 标记已访问节点
visited(node) = true;
% 输出当前节点
disp(node);
% 遍历当前节点的每一个邻接节点
num  = 1;
while 1
    if num >= size(Map(1, :))
        break;
    end
    sumnode = sum(Map(node, :)); % 判断当前节点是否有邻接节点
    if sumnode > 0.5% 有邻接节点,继续查找
        for i = 1:length(Map(node, :))  % 对于当前节点的每一个邻接节点
            if Map(node, i) > 0.5% 判断是否与当前节点连接
                if ~visited(i)  % 如果邻接节点没有被访问过
                    num = num + 1;
                    queue= [queue; node];
                    nodepre(i) = node;% 记录前序节点
                    node = i;
                    visited(node) = true;
                    Map(node, i) = 0;
                    % 输出当前节点
                    disp(node);
                end
            end
        end
    else %无邻接节点,节点回溯
        node = queue(end);
        queue(end) = [];
        % 输出当前节点
        disp(node);
    end
end
end

运行结果:

从结果可以看出,算法先沿1-2-3搜寻,发现节点3无邻接节点后,回溯回节点2,从节点2沿2-4-5-6搜寻直到找到终点6。

4 与BFS对比

之前我们用迷宫问题做了BFS算法算例,这里用DFS算法实现对比一下:

BFS算法搜寻过程:

DFS算法搜寻过程:

可以看出采用广度优先算法(BFS)时,搜寻范围大,需遍历图中的所有节点,但是BFS算法输出的路径是最优的;而深度优先算法(DFS)所需胡搜寻范围较小,搜寻速度快,但是得到的搜寻路径不能保证最优。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

宇智波-二柱子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值