数据结构与算法C++之图的广度优先遍历

(1)首先取出节点0放入队列中
《数据结构与算法C++之图的广度优先遍历》
(2)开始遍历,首先将列首的元素0取出队列,然后将与0相连接的节点1,2,5,6,推入队列
《数据结构与算法C++之图的广度优先遍历》
(3)继续将队首的元素1取出队列,然后将与节点1相连接的节点0推入队列,由于节点0已经在队列中,所以不需要操作,继续将队首的元素2取出队列,此时与2连接的节点0已经在队列中,也不进行操作;继续将队首的元素5取出队列,然后将与5连接的节点0,3,4推入队列中,由于0已经在队列中,所以只推入3和4,
《数据结构与算法C++之图的广度优先遍历》
(4)继续取出队首的元素6,然后由于与6相连接的节点0和4都已经在队列中,所以不操作
《数据结构与算法C++之图的广度优先遍历》
(5)继续将队首的元素3取出队列,与3相连接的节点4,5都在队列中,不操作;继续将队首的元素4取出队列,与4相连接的节点3,5,6都已经在队列中,所以不操作;此时队列为空,遍历结束
《数据结构与算法C++之图的广度优先遍历》
可以看出广度优先遍历遍历出的节点是按距离大小顺序排列的
《数据结构与算法C++之图的广度优先遍历》

广度优先遍历实现程序 ShortestPath.h

//ShortestPath.h

#include <stack>
#include <iostream>
#include <cassert>
#include <queue>

using namespace std;

template <typename Graph>
class ShortestPath{

private:
    Graph &G;
    int s;
    bool *visited;
    int *from;
    int *ord;

public:
    ShortestPath(Graph &graph, int s):G(graph){

        //算法初始化
        assert( s >= 0 && s < G.V() );

        visited = new bool[G.V()];
        from = new int[G.V()];
        ord = new int[G.V()];
        for ( int i = 0; i < G.V(); i++){
            visited[i] = false;
            from[i] = -1;
            ord[i] = -1;
        }
        this->s = s;

        queue<int> q;
        //无向图最短路径算法
        q.push(s);
        visited[s] = true;
        ord[s] = 0;
        while ( !q.empty() ){
            int v = q.front();
            q.pop();

            typename Graph::adjIterator adj(G, v);
            for ( int i = adj.begin(); !adj.end(); i = adj.next() ){
                if ( !visited[i] ){
                    q.push(i);
                    visited[i] = true;
                    from[i] = v;
                    ord[i] = ord[v] + 1;
                }
            }
        }
    }

    ~ShortestPath() {
        delete[] visited;
        delete[] from;
        delete[] ord;
    }

    bool hasPath(int w){
        assert( w >= 0 && w < G.V() );
        return visited[w];
    }

    void path(int w, vector<int> &vec){

        assert( w >= 0 && w < G.V() );

        stack<int> s;

        int p = w;
        while ( p != -1 ){
            s.push(p);
            p = from[p];
        }

        vec.clear();
        while ( !s.empty() ){
            vec.push_back( s.top() );
            s.pop();
        }
    }

    void showPath(int w){
        vector<int> vec;
        path(w, vec);
        for(int i = 0; i < vec.size(); i ++){
            cout<<vec[i];
            if(i == vec.size() - 1)
                cout<<endl;
            else
                cout<<" -> ";
        }
    }

    int length(int w){
        assert( w >= 0 && w < G.V() );
        return ord[w];
    }
};

测试程序如下

#include <ctime>
#include <cstdlib>
#include "SparseGraph.h"
#include "DenseGraph.h"
#include "ReadGraph.h"
#include "Path.h"
#include "ShortestPath.h"

using namespace std;

int main()
{
    string filename = "testG2.txt";
    SparseGraph g = SparseGraph( 7, false );
    ReadGraph<SparseGraph> readGraph( g, filename );
    g.show();
    cout<<endl;

    Path<SparseGraph> dfs( g, 0 ); //深度优先遍历
    cout<<"DFS : ";
    dfs.showPath(6);

    ShortestPath<SparseGraph> bfs(g, 0); //广度优先遍历
    cout<<"BFS : ";
    bfs.showPath(6);

    return 0;
}

上面程序中调用的头文件见上篇博客(数据结构与算法C++之图的获得两点之间的一条路径
输出结果为
《数据结构与算法C++之图的广度优先遍历》
可以看出深度优先遍历遍历了4次才到节点6
而广度优先遍历遍历了1次就到了节点6
《数据结构与算法C++之图的广度优先遍历》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/majinlei121/article/details/84571611
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞