C++中图的BFS和DFS

Posted

技术标签:

【中文标题】C++中图的BFS和DFS【英文标题】:BFS and DFS of a graph in C++ 【发布时间】:2014-12-12 00:08:07 【问题描述】:

我一直在尝试对我的图表进行 BFS 和 DFS。我已经尝试了一切,但仍然无法弄清楚我的算法有什么问题。请帮我解决这个问题。

我将顶点与我的向量一起发送到 bfs 和 bfs,以便通过它并寻找正确的值。我对此很陌生,并且在尝试解决它时遇到了很多问题。如果有人可以通过我的代码并查看我的算法哪里错了,那就太好了。我希望一双新的眼睛能够发现问题。

它确实显示了输出但错误!

这是我的图表输入值:: 5 1, 5 2, 5 3, 1 4, 1 6

这里1是5的边缘,2是5的边缘,3是5的边缘等等......

这是我得到的输出: 对于 BFS: 5,1,2,3,4,6

对于 DFS: 5,4,3,2,1,5

这是我的算法:

#ifndef SORT_HPP
#define SORT_HPP

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <list>
#include <vector>
#include <stack>
#include <algorithm>
#include "clsVertex.hpp"
#include "clsFileGraph.hpp"
#include "clsGraph.hpp";

class bfs : public clsGraph
    int vert;

public:
    bfs(int s, vector<clsVertex*> verticies); //prints BFS traversal from a given source

;

class dfs: public clsGraph
    int vert;
    list<int> adj;

public:
    dfs(int s, vector<clsVertex*> verticies);   //prints DFS traversal from a given source

;

bfs::bfs(int s, vector<clsVertex*> verticies)

    bool *visited = new bool[verticies.size()]; //creates a new boolean array of the size of the graph

    for (int i = 0; i < verticies.size(); i++) //loops till the end of the graph
        int x = verticies[i]->ID;   //gets the value of each vertex
            //cout << "The val: " << verticies[i]->ID << endl;
            visited[x] = false; //marks that vertex as unvisited i.e: visited = false
    

    list<int> queue;    //creates a queue
    visited[s] = true;  //marks the starting point as visited
    queue.push_back(s); //adds the starting point to the queue
    cout << endl << "The breath first sort is as follows:-" << endl << endl;
    while (queue.size() != 0)  //loops until the size of the queue is 0 
        for (int i = 0; i < verticies.size(); i++) //loops 
            int y = verticies[i]->edges.size();
            for (int j = 0; j < y; j++)
                int z = verticies[i]->edges[j]->ID;

                if (visited[z]== false)
                    visited[z] = true;
                    queue.push_back(z);
                

            
        
        cout << s << ",";
        queue.pop_front();
        if (queue.size() == 0)
            goto here;
        s = queue.front();

    
    here:
    cout << ID << " " << graphType << endl;
    for (int i = 0; i < verticies.size(); i++)
        cout << verticies[i]->ID << "->";
        for (int j = 0; j < verticies[i]->edges.size(); j++)
            cout << verticies[i]->edges[j]->ID << endl;
        
    

    cout << endl << endl << "Done" << endl << endl;





// DFS traversal of the vertices reachable from v. It uses recursive DFSUtil()
dfs::dfs(int s, vector<clsVertex*> verticies)

    // Mark all the vertices as not visited
    bool *visited = new bool[verticies.size()]; //creates a new boolean array of the size of the graph

    for (int i = 0; i < verticies.size(); i++) //loops till the end of the graph
        int x = verticies[i]->ID;   //gets the value of each vertex
        //cout << "The val: " << verticies[i]->ID << endl;
        visited[x] = false; //marks that vertex as unvisited i.e: visited = false
    
    stack <int> depth;
    visited[s] = true;
    depth.push(s);
    //cout << s << ",";
    while (depth.size() != 0)  //loops until the size of the queue is 0 
        for (int i = 0; i < verticies.size(); i++) //loops 
            int y = verticies[i]->edges.size();
            for (int j = 0; j < y; j++)
                int z = verticies[i]->edges[j]->ID;

                if (visited[z] == false)
                    visited[z] = true;
                    depth.push(z);
                

            
        
        cout << s << ",";
        depth.pop();
        if (depth.size() == 0)
            goto there;
        s = depth.top();

    
there:
    cout << "done";


#endif

【问题讨论】:

为什么会有一个指向列表的指针?您几乎不需要指向容器的指针。 哪一个是错的? BFS 还是 DFS?此外,如果您发布了错误的输出,这可能会有所帮助。 我认为他们都错了。我也会在问题中添加输入和输出。 @YRK:BFS 结果在我看来是正确的,这令人惊讶,因为这是更难的算法 @MooingDuck:谢谢。我对它是对还是错感到困惑。但我仍然很难找出 DFS 的正确答案。 【参考方案1】:

您的 BFS 方法不起作用,因为您将所有顶点都添加到队列中。您应该将 while ( queue.size &gt; 0 ) 循环的内部替换为:

s = queue.pop_front();
for ( int i = 0; i < vertices[s]->edges.size(); i++ ) 
    int tmp = vertices[s]->edges[i]->ID;
    if ( !visited[tmp] ) 
        visited[tmp] = true;
        queue.push_back(tmp);
    

cout << s << " ";

正如您目前所拥有的那样,您添加顶点 1 的邻居,然后添加顶点 2,甚至不引用您假定的起点 s。您只需要添加当前位于队列前面的任何顶点的邻居。

【讨论】:

他的 BFS 输出是正确的,尽管我承认我没有阅读代码。不过,他的 DFS 输出显然是错误的,它列出了两次 5,而根本没有列出 6 @Mooing Duck 我的猜测是他的 BFS 输出正确是侥幸,但我可能错了。 @YRK:您应该阅读代码并了解其工作原理,而不是简单地复制粘贴。这应该在正确使用时打印所有值,并且仅在使用不当时打印5

以上是关于C++中图的BFS和DFS的主要内容,如果未能解决你的问题,请参考以下文章

图的遍历方法——DFS和BFS

图论算法之DFS与BFS

C++笔记-二维棋盘数组使用BFS(宽度优先遍历)

我的 C++ 程序中的一些代码使程序崩溃。我正在实现 BFS 算法

C++笔记-基于邻接矩阵的BFS(宽度优先遍历)

C++笔记-基于邻接表的BFS(宽度优先遍历)