BFS(广度优先搜索)邻接矩阵C ++

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BFS(广度优先搜索)邻接矩阵C ++相关的知识,希望对你有一定的参考价值。

我正在尝试学习具有邻接矩阵的BFS(广度优先搜索)。

我尝试了什么:

  • 我真的不知道BFS到底是什么,所以我学会了概念和伪代码
  • 试着看例子
  • 尝试使用指向下面的数组版本的指针实现

目的:

  • 我想确保使用指向数组矩阵的指针正确地进行BFS

邻接矩阵的图类:

#include <iostream>
#include <queue>
using namespace std;

class Graph {
private:
    bool** adjMatrix;
    int numVertices;
    bool* visited;
public:
    //constructor
    Graph(int numVertices) {
        this->numVertices = numVertices;
        adjMatrix = new bool*[numVertices];
        for(int i = 0; i < numVertices; i++) {
            adjMatrix[i] = new bool[numVertices];
            for(int j = 0; j < numVertices; j++)
                adjMatrix[i][j] = false;
        }

        visited[numVertices]; //init visited array


    }

    //member function
    void BFS(int sp) {
        //make a queue of type int
        queue<int> Q;

        //make bool visited array & mark all positions unvisited
        for(int i = 0; i < numVertices; i++)
            visited[i] = false;

        //push sp into queue
        Q.push(sp);

        //mark sp as visited
        visited[sp] = true;

        //while queue isn't empty
        while(!Q.empty()) {

            //make temp node
            int temp = Q.front();

            //pop temp node
            Q.pop();

            //use loop & check if it has children
            int rows =  sizeof adjMatrix / sizeof adjMatrix[0]; //get row size
            for(int i = 0; i < rows; i++) { //check neighboring nodes
                if(!visited[i] && adjMatrix[sp][i] == true) {
                    Q.push(i); //if so push them into queue
                    visited[i] = true; //mark children as visited
                }
            }
        }

    }



};
答案

好的,因为您没有附加错误日志或测试用例输出,请考虑以下实现

#include <iostream>
#include <queue>
#include <vector>
#include <set>
#include <cstdlib>

// using namespace std;   Don't do this. Good CPP production code uses separate namespaces 

const int BUFFER_CLEAR_VALUE = 999;

class Graph {
private:
    std::vector<std::vector<bool> > adj_mat;

public:
    //constructor
    Graph() {
        std::cout << "Enter vertex num" << std::endl;
        int num_vertices;
        std::cin >> num_vertices;
        while (std::cin.fail()) {
            std::cout << "Enter a valid num" << std::endl;
            std::cin.clear();
            std::cin.ignore(BUFFER_CLEAR_VALUE, '
');
            std::cin >> num_vertices;
        }
        for (int i = 0; i < num_vertices; i++) {
            std::vector<bool> temp;
            temp.resize(num_vertices);
            adj_mat.push_back(temp);
        }
    }

    // member fn
    void initialize() {
        for (int i = 0; i < adj_mat.size(); i++) {
            for (int j = 0; j < adj_mat[0].size(); j++) {
                char choice;
                do {
                    std::cout << "Enter adj mat value for [y/n] " << i << ":" << j << std::endl;
                    std::cin >> choice;
                    if (choice == 'y') {
                        adj_mat[i][j] = true;
                    } else {
                        adj_mat[i][j] = false;
                    }

                    if (std::cin.fail() || (choice!='y' && choice!='n' )) {
                        std::cout << "enter a valid value please!!" << std::endl;
                        std::cin.clear();
                        std::cin.ignore(BUFFER_CLEAR_VALUE,'
');
                    }
                } while( std::cin.fail() || (choice!='y' && choice!='n' ));
            }
        }
    }

    // member fn
    void showMatrix() {
        std::cout << std::endl << "Adjacency Matrix" << std::endl;
        for (int i = 0; i < adj_mat.size(); i ++) {
            for (int j = 0; j < adj_mat[i].size(); j++) {
                std::cout << adj_mat[i][j] << "	";
            }
            std::cout << std::endl;
        }
    }

    // member fn
    void breadthFirstSearch(int start_point, int end_point) {
        std::queue<int> vertex_queue;
        std::set<int> visited_vertices;
        vertex_queue.push(start_point);

        while(!vertex_queue.empty()) {
            // Get next vertex
            int current_vertex = vertex_queue.front();
            vertex_queue.pop();

            // Make note of current visit
            visited_vertices.insert(current_vertex);
            std::cout << "Looking at " << current_vertex << std::endl;

            for (int j = 0; j < adj_mat[current_vertex].size(); j++) {
                if (adj_mat[current_vertex][j]) {
                    if (j == end_point) {
                        std::cout << "Found it " << j << std::endl;
                        return;
                    } else if (!(visited_vertices.find(j) != visited_vertices.end())) {
                        vertex_queue.push(j);
                    }
                }
            }
        }
        std::cout << "Could not find it!" << std::endl;
    }
};


int main() {
    Graph g;
    g.initialize();
    g.showMatrix();
    g.breadthFirstSearch(0, 1);
    g.breadthFirstSearch(0, 4);
    return 0;
}

有些观点

  • 这是C ++,为什么不使用vector等为你处理内存之类的东西呢? (如果这不是你想要的,你没有表明)
  • BFS背后的关键理念是 查看当前节点的所有邻居,开始处理邻居的邻居 如果之前没有,则只处理节点
  • 你这样做的方式什么都没有。矩阵只有false。你有意在某个时候改变它吗?
  • 你的大小计算是错误的,它们仅在指针上运行!
  • 你没有有效的终止标准。你在寻找什么BFS?您还需要知道何时停止搜索。并报告发生的事情
  • 我改变了什么 改为使用cpp的std容器 删除了using namespace std;的用法 在main提供了一个非常基本的测试用例 添加了初始化和打印矩阵的方法

运行我上面分享的代码,就像这样的图形

Simple Graph

$ ./Adjacency                       
Enter vertex num                             
5                                            
Enter adj mat value for [y/n] 0:0            
y                                            
Enter adj mat value for [y/n] 0:1            
y                                            
Enter adj mat value for [y/n] 0:2            
n                                            
Enter adj mat value for [y/n] 0:3            
n                                            
Enter adj mat value for [y/n] 0:4            
n                                            
Enter adj mat value for [y/n] 1:0            
y                                            
Enter adj mat value for [y/n] 1:1            
y                                            
Enter adj mat value for [y/n] 1:2            
y                                            
Enter adj mat value for [y/n] 1:3            
y                                            
Enter adj mat value for [y/n] 1:4            
n                                            
Enter adj mat value for [y/n] 2:0            
n                                            
Enter adj mat value for [y/n] 2:1            
y                                            
Enter adj mat value for [y/n] 2:2
y
Enter adj mat value for [y/n] 2:3
n
Enter adj mat value for [y/n] 2:4
n
Enter adj mat value for [y/n] 3:0
n
Enter adj mat value for [y/n] 3:1
y
Enter adj mat value for [y/n] 3:2
n
Enter adj mat value for [y/n] 3:3
y
Enter adj mat value for [y/n] 3:4
n
Enter adj mat value for [y/n] 4:0
n
Enter adj mat value for [y/n] 4:1
n
Enter adj mat value for [y/n] 4:2
n
Enter adj mat value for [y/n] 4:3
n
Enter adj mat value for [y/n] 4:4
y

Adjacency Matrix
1       1       0       0       0
1       1       1       1       0
0       1       1       0       0
0       1       0       1       0
0       0       0       0       1
Looking at 0
Found it 1
Looking at 0
Looking at 1
Looking at 2
Looking at 3
Could not find it!

建议可能的改进

  1. 摘要功能更好,现在Graph是一个神级
  2. 不要在其中列=行的邻接矩阵中收集输入的输入
  3. 根据先前的值推断矩阵的值,例如:如果1接近2,那么您知道2紧跟在1之后
  4. 处理输入越来越好,我已经忘记了cin东西的干净方式

If you insist on pointers to arrays all you ned to do is change the constructor and .size() invocations.

以上是关于BFS(广度优先搜索)邻接矩阵C ++的主要内容,如果未能解决你的问题,请参考以下文章

图的深度优先遍历DFS和广度优先遍历BFS(邻接矩阵存储)超详细完整代码进阶版

c语言图的遍历,邻接表存储,深度,广度优先遍历

求算法,用邻接矩阵和邻接表创建一个图,实现深度和广度搜索,菜单形式,c语言的代码。无向无权的图。

优秀题解问题 1703: 图的遍历——广度优先搜索

图解:深度优先搜索与广度优先搜索

C语言实现图的广度优先搜索遍历算法