zoukankan      html  css  js  c++  java
  • 广度优先搜索

    广度优先搜索是最简单的图搜索算法之一,也是许多重要的图算法原型。

    算法描述:

        给定图G=(V,E)和一个可识别的源结点s, 广度优先搜索对图G中的边进行系统性的搜索来发现从源结点s可以到达的所有结点。

    该算法能够计算从s到每个可达节点的最短距离(即最少边数),同时生成一颗“广度优先搜索树”。

        该算法既可以用于无向图,也可以用于有向图。

        该算法需要先发现所有到源结点s的距离为k的所有结点,之后才会去发现到源结点s距离为k+1的结点。

    算法适用:

        通常用来寻找从一个特定源结点出发的最短路径距离。

    广度优先搜索树

        该树以源节点s为根节点,包含所有s可到达的结点,树中s到可到达节点v的距离,即为简单图中s到v的最短距离。

        注:搜索树中的边是图中存在的边,而删除了部分的边,构成一棵无环的图,即树。

            搜索树中的边是搜索过程中搜索到该结点所依附的那个边,如下左图所示。

            若出发点是a,则a通过1搜索到d,d通过2搜索到b,d通过3搜索到c,所以搜索树如下右图所示

                    

                   将广度优先搜索树中的边改为有向边,即为前驱子图。其数学定义为:

                 

                    v.pre为v的前驱结点,该前驱图的结点由源结点s和其余前驱非空的结点组成。

    算法实现: 

    1. 邻接矩阵法

    int visited[N];
    int edges[N][N];
    
    void BFS(int start)
    {
        queue<int> mq;
        memset(visited, 0, sizeof(visited));
    
        mq.push(start);
        visited[start] = 1;
    
        while(mq.empty() == false)
        {
            int id = mq.front();
            mq.pop();
    
            for(int i = 0; i < N; i++)
            {
                if(edges[id][i] == 1 && visited[i] == 0)
                {
                    visited[i] = 1;
                    mq.push(i);
                }
            }
        }
    }
    

    2. 邻接链表法(用数组模拟) 

    int visited[N];
    vector<int> v[N];
    
    void BFS(int start)
    {
        queue<int> mq;
        memset(visited, 0, sizeof(visited));
        
        mq.push(start);
        visited[start] = 1;
    
        while(mq.empty() == false)
        {
            int id = mq.front();
            mq.pop();
    
            for(int i = 0; i < v[id].size(); i++)
            {
                if(visited[i] == 0)
                {
                    to = v[id][i];
                    visited[to] = 1;
                    q.push(to);
                }
            }
        }
    }
    

      

    邻接链表法时间复杂度分析:

        使用聚合分析法进行整体分析,每个结点入队最多一次,出队最多一次,入队和出队的时间均为O(1),因此对队列进行操作的总时间为O(V)。

        因此第21行到第23行的时间复杂度是O(V),因为这三行成线性关系,因此只考虑队列操作。

        现在考虑循环和条件判断,会对每条边进行扫描,因此12行到19行的时间复杂度为O(E)。

        因此总时间复杂度为O(V+E)。

  • 相关阅读:
    一个奇怪的SystemClock_Config问题解决方法
    Keil5下载STM32库
    Entry point (0x08000000) points to a Thumb instruction but is not a valid Thumb code pointer.
    Error: failed to execute 'C:KeilARMARMCC'的解决办法
    C#委托的介绍(delegate、Action、Func、predicate)
    CopyFromScreen在屏幕缩放情况下需要做处理
    C# CEF 封装UserControl
    一个单js文件也可以运行vue
    vue自学入门-3(vue第一个例子)
    vue自学入门-1(Windows下搭建vue环境)
  • 原文地址:https://www.cnblogs.com/yanghh/p/12676263.html
Copyright © 2011-2022 走看看