zoukankan      html  css  js  c++  java
  • 【数据结构】图的广度优先搜索

      图的广度优先搜索(BFS)与树的广度优先搜索类似。与树不同的是,图中可能存在循环。所我们可能会再次访问到同一个节点。为了表面多次处理同一个节点,我们要布尔变量数据记录节点有没有被访问过。为了简化,我们假设所有的节点都是从根节点可达的。

      比如在下图中,我们从节点2出发。当我们访问到节点0时,我们寻找所有与他相邻的节点。节点2就是与0相邻的节点,如果我们不对已访问的节点做标记,那么节点2就会被重复访问。这样的话,算法将会一直进行下去。对下图进行广度优先搜索的结果是2,0,3,1.  

      

      以下C++程序是从给定节点进行广度优先搜索的一个简单实现。图的存储使用了邻接链表法。STL的list容器用来存储邻接节点以及与广度优先搜索需要的节点队列。

    #include<list>
    #include<iostream>
    //Program to print BFS traversal from a given source vertex. BFS(int s)
    //traverses vertices reachable from s 
    using namespace std;
    
    //The class represents  a directed graph using adjacency lists
    class Graph {
        int V;    //No. of vertices
        list<int> *adj;
     public:
         Graph(int V);    //Constructor
         ~Graph();
         void addEdge(int v, int w);    //function to add an edge to graph
         void BFS(int s);    //print BFS traversal from a given source s
    };
    
    Graph::Graph(int V) {
        this->V = V;
        adj = new list<int>[V];
    }
    
    Graph::~Graph() {
        delete []adj;
    }
    
    void Graph::addEdge(int v, int w) {
        adj[v].push_back(w);
    }
    
    void Graph::BFS(int s) {
        //Mark all the vertices as not visited
        bool *visited = new bool[V];
        for (int i = 0; i < V; i++) {
            visited[i] = false;
        }
    
        //Create a queue for BFS
        list<int> queue;
    
        queue.push_back(s);
    
        //"i" will be used to get all adjacent vertices of vertex
        list<int>::iterator i;
    
        while (!queue.empty()) {
            //Dequeue a vertex from queue and print it
            s = queue.front();
            cout<<s<<" ";
            queue.pop_front();
            visited[s] = true;
    
            //Get all adjacent vertices of the Dequeued vertex s
            //If a adjacent has not been visited, then mark it visited 
            //and enqueue it
            for (i = adj[s].begin(); i != adj[s].end(); i++) {
                if (!visited[*i]) {
                    queue.push_back(*i);
                }
            }
        }
    
        delete []visited;
    }
    
    int main()
    {
         // Create a graph given in the above diagram
        Graph g(4);
        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(1, 2);
        g.addEdge(2, 0);
        g.addEdge(2, 3);
        g.addEdge(3, 3);
     
        cout << "Following is Breadth First Traversal (starting from vertex 2) 
    ";
        g.BFS(2);
     
        return 0;
    }

    参考资料

      1. http://www.geeksforgeeks.org/breadth-first-traversal-for-a-graph/

  • 相关阅读:
    Spring笔记:常用xml标签和属性 山上下了雪
    Spring笔记:Hello World 山上下了雪
    Spring笔记:bean的自动装配 山上下了雪
    IntelliJ IDEA 2020.3.3 x64破解到2099年
    每日长进计划
    idea测试类中的测试方法没有运行按钮
    删除所有的phpfpm进程命令
    高质量编程
    单例模式也能玩出花
    宝塔Linux面板安装命令
  • 原文地址:https://www.cnblogs.com/vincently/p/4769422.html
Copyright © 2011-2022 走看看