• MATLAB 广度优先搜索BFS、深度优先搜索DFS


    如此经典的算法竟一直没有单独的实现过,真是遗憾啊。

    广度优先搜索在过去实现的二值图像连通区域标记和prim最小生成树算法时已经无意识的用到了,深度优先搜索倒是没用过。

    这次单独的将两个算法实现出来,因为算法本身和图像没什么关系,所以更纯粹些。

    广度优先搜索是从某一节点开始,搜索与其线连接的所有节点,按照广度方向像外扩展,直到不重复遍历所有节点。

    深度优先搜索是从某一节点开始,沿着其搜索到的第一个节点不断深入下去,当无法再深入的时候,回溯节点,然后再在回溯中的某一节点开始沿另一个方向深度搜索,直到不重复的遍历所有节点。

    广度优先搜索用的是队列作为临时节点存放处;深度优先搜索可以递归实现(算法导论就是用递归实现的伪代码),不过我这里是用栈作为临时节点存放处。

    感觉也没什么好介绍的了,抄算法导论上的介绍也没什么意思,所有的内容都是书上的,真正学东西还是要看书。

    下面是运行结果:

    原连通图:

    广度优先搜索:

    深度优先搜索:

    matlab代码如下,其中的画图函数netplot.m。

    BFS.m

     1 clear all;close all;clc
     2 %初始化邻接压缩表
     3 b=[1 2;1 3;1 4;2 4;
     4    2 5;3 6;4 6;4 7];
     5 
     6 m=max(b(:));                %压缩表中最大值就是邻接矩阵的宽与高
     7 A=compresstable2matrix(b);  %从邻接压缩表构造图的矩阵表示
     8 netplot(A,1)                %形象表示
     9 
    10 head=1;             %队列头
    11 tail=1;             %队列尾,开始队列为空,tail==head
    12 queue(head)=1;      %向头中加入图第一个节点
    13 head=head+1;        %队列扩展
    14 
    15 flag=1;             %标记某个节点是否访问过了
    16 re=[];              %最终结果
    17 while tail~=head    %判断队列是否为空
    18     i=queue(tail);  %取队尾节点
    19     for j=1:m
    20         if A(i,j)==1 && isempty(find(flag==j,1))    %如果节点相连并且没有访问过
    21             queue(head)=j;                          %新节点入列
    22             head=head+1;                            %扩展队列
    23             flag=[flag j];                          %对新节点进行标记
    24             re=[re;i j];                            %将边存入结果
    25         end
    26     end
    27     tail=tail+1;            
    28 end
    29 
    30 A=compresstable2matrix(re);
    31 figure;
    32 netplot(A,1)

    DFS.m

     1 clear all;close all;clc
     2 %初始化邻接压缩表
     3 b=[1 2;1 3;1 4;2 4;
     4    2 5;3 6;4 6;4 7];
     5 
     6 m=max(b(:));                %压缩表中最大值就是邻接矩阵的宽与高
     7 A=compresstable2matrix(b);  %从邻接压缩表构造图的矩阵表示
     8 netplot(A,1)                %形象表示
     9 
    10 top=1;                  %堆栈顶
    11 stack(top)=1;           %将第一个节点入栈
    12 
    13 flag=1;                 %标记某个节点是否访问过了
    14 re=[];                  %最终结果
    15 while top~=0            %判断堆栈是否为空
    16     pre_len=length(stack);    %搜寻下一个节点前的堆栈长度
    17     i=stack(top);             %取堆栈顶节点
    18     for j=1:m
    19         if A(i,j)==1 && isempty(find(flag==j,1))    %如果节点相连并且没有访问过 
    20             top=top+1;                          %扩展堆栈
    21             stack(top)=j;                       %新节点入栈
    22             flag=[flag j];                      %对新节点进行标记
    23             re=[re;i j];                        %将边存入结果
    24             break;   
    25         end
    26     end    
    27     if length(stack)==pre_len   %如果堆栈长度没有增加,则节点开始出栈
    28         stack(top)=[];
    29         top=top-1;
    30     end    
    31 end
    32 
    33 A=compresstable2matrix(re);
    34 figure;
    35 netplot(A,1)

    compresstable2matrix.m

     1 function A=compresstable2matrix(b)
     2     [n ~]=size(b);
     3     m=max(b(:));
     4     A=zeros(m,m);
     5 
     6     for i=1:n
     7         A(b(i,1),b(i,2))=1;
     8         A(b(i,2),b(i,1))=1;
     9     end
    10 
    11 end
  • 相关阅读:
    char/unsigned char/int/short 存储范围
    js 数字数组按大小排序
    【转】Vue生命周期
    mvn+spring+webapp模板
    【转存】Vue组件选项props
    eclipse -- git 显示修改历史 对比文件
    eclipse -- git 提示
    mysql -- 查询并插入
    git --eclipse -- 下载超时
    mysql -- 字符串长度
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13646646.html
Copyright © 2020-2023  润新知