• BFS DFS


    BFS 和 DFS是简单且重要的图遍历算法。

    BFS

    BFS 可以计算出源节点S到任意可达节点的距离(一条简单路径,且经过的边数最少),或者说,在所有边的权重为1的情况下,源节点和任意可达节点的最短距离。算法始终在发现节点和未发现节点之间扩展,也就是说沿广度方向扩展。笼统的说:总会先发现,距离源节点为k的节点,然后才会发现距离源节点为k+1的节点。

    伪代码

    首先约定每个节点p拥有属性d和f,d用于标记当前节点与源节点的距离,f用于标记当前节点是否被发现。使用p.d, p.f的形式访问相应的属性。

        BFS(S)
            将除去源节点S以外的所有节点的到源节点距离d设为INF(无穷大),标记属性f为未发现。
            将源节点d设为0,f设为已发现。
            新建一个空队列q。
            将节点S放入队列q中。
            在队列不为空的情况下,重复以下操作:
                    1.将队首元素u取出。
                    2.将u的所有相邻且未发现节点属性d设为u.d + 1,属性f设为 已发现,并放入队列q中。
                    3.返回操作1。
    

    时间复杂度

    对于图G(V,E),因为每条边被访问次数为O(1),每个节点入队和出队一次,时间复杂度为 O(1),总的复杂度 为O(V+E).

    DFS

    DFS在运行过程中,节点的首次发现时间u.sd和发现完成时间u.fd(发现完成:所有相邻接点均被发现)是比较有用的属性。DFS总是沿着最近发现的节点进行探索,假设发现了节点u,并且节点u可达且未被发现的相邻接点为:v1,v2,v3,,vk.且从u出发访问的次序也是这个次序。算法会先发现v1,然后将v1所有可达节点发现完毕后,算法会返回上一层到u,然后从v2开始,重复以上操作。

    伪代码

        DFS()
            将所有节点的标记属性f为未发现。
            全局属性时间 t = 0;
            对每一个未发现的节点u,然后,执行DFS_VISIT(u):
    
        DFS_VISIT(s)
            将节点s的发现时间设为s.sd = ++t;
            属性f设为:已发现
            对节点s相邻且未发现的所有节点执行DFS_VISIT(v);
            将节点s的发现完成时间s.fd = ++t;
    

    时间复杂度

    和BFS分析方法类似,可得:O(V+E);

    应用

    BFS,DFS是搜索常用的策略,根据需要进行属性的添加和删除,DFS还可以用于拓扑排序。

    主要参考: 算法导论

  • 相关阅读:
    线性支持向量机分类
    字符识别--模型集成
    字符识别--模型的训练与验证
    反射案例当中pro.load()报错问题的解决
    字节码对象功能
    BS案例服务器之系统找不到指定路径
    内部类接口实现线程
    多个异常,一次捕获,多次处理
    Objects.requireNonNull
    intellij idea编译java出现kotlin:connecting to daemon
  • 原文地址:https://www.cnblogs.com/lif323/p/9417768.html
Copyright © 2020-2023  润新知