当前位置: 首页 > 知识库问答 >
问题:

广度优先搜索:有向图

桂阳文
2023-03-14

我正在尝试在有向图上实现BFS。我完全确定我的算法是正确的,但是,下面的代码段返回错误:

图表。CPP文件:

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

class node{
    int value;
    int color;


    public:
        list <node> adj;
        node(int val){
            value = val;
            color = 0;
        }

        void add_edge(node x){
            adj.push_back(x);
        }

        void change_color(int c){
            color = c;
        }

        int get_color(){
            return color;
        }

        int get_value(){
            return value;
        }
};

以及在以下方面的实际BFS实施:

#include "graph.cpp"
node n0(0),n1(1),n2(2),n3(3), n4(4);

//PrintQ: Print the list
void printq( list <node> A){
    while (!A.empty())
    {
        cout << A.front().get_value() <<" ";
        A.pop_front();
    }
}

void bfs(node s){
    list <node> q;
    q.push_back(s);
    s.change_color(1);

    while(!q.empty()){
        node s = q.front();

        cout<<s.get_value()<<'\t';
        printq(s.adj);      
        cout<<endl;

        list<node>::iterator i;
        for(i = s.adj.begin(); i != s.adj.end(); ++i){

            if((*i).get_color() == 0){
                q.push_back(*i);
                (*i).change_color(1);
            }
        }

        q.pop_front();
    }

}
int main(){

    n0.add_edge(n1);
    n0.add_edge(n2);
    n1.add_edge(n2);
    n2.add_edge(n0);
    n2.add_edge(n3);
    n0.add_edge(n3);
    n1.add_edge(n4);
    n4.add_edge(n3);
/*  
    printq(n0.adj);cout<<endl;
    printq(n1.adj);cout<<endl;
    printq(n2.adj);cout<<endl;
*/
    bfs(n1);

    return 0;

因此,除了源节点之外,队列中的其他节点都给出了错误的邻接列表。虽然队列顺序运行良好,但队列中的节点给出了错误的邻接。

我不确定为什么会发生这种情况,虽然我怀疑这是由于按值复制节点而不是引用。

这是我在很长一段时间后的CPP计划,所以如果我错过了什么,请启发我。

提前感谢帮助。

共有1个答案

相化
2023-03-14

您准确地说明了问题。当您添加“n1.add_edge(n2);”时,n2没有任何边,n1将保留n2的副本。后来,当您向n2添加更多边时,n1的副本不会改变。我修改了您的代码以使用指针,我认为它现在可以正常工作了。

#include<iostream>
#include <list>
using namespace std;
class node{
    int value;
    int color;


    public:
        list <node * > adj;
        node(int val){
            value = val;
            color = 0;
        }

        void add_edge(node * x){
            adj.push_back(x);
        }

        void change_color(int c){
            color = c;
        }

        int get_color(){
            return color;
        }

        int get_value(){
            return value;
        }
};

和您的主文件

#include "graph.cpp"

//PrintQ: Print the list
void printq( list <node *> A){
    while (!A.empty())
    {
        cout << A.front()->get_value() <<" ";
        A.pop_front();
    }
}

void bfs(node * s){
    list <node *> q;
    q.push_back(s);
    s->change_color(1);

    while(!q.empty()){
        node * s = q.front();

        cout<<s->get_value()<<'\t';
        printq(s->adj);      
        cout<<endl;

        list<node * >::iterator i;
        for(i = s->adj.begin(); i != s->adj.end(); ++i){

            if((*i)->get_color() == 0){
                q.push_back(*i);
                (*i)->change_color(1);
            }
        }

        q.pop_front();
    }

}
int main(){

    node* n0 = new node(0);
    node* n1 = new node(1);
    node* n2 = new node(2);
    node* n3 = new node(3);
    node* n4 = new node(4);

    n0->add_edge(n1);
    n0->add_edge(n2);
    n1->add_edge(n2);
    n2->add_edge(n0);
    n2->add_edge(n3);
    n0->add_edge(n3);
    n1->add_edge(n4);
    n4->add_edge(n3);
/*  
    printq(n0.adj);cout<<endl;
    printq(n1.adj);cout<<endl;
    printq(n2.adj);cout<<endl;
*/
    bfs(n1);
    delete n0, n1, n2, n3, n4;
}
 类似资料:
  • 主要内容:深度优先搜索(简称“深搜”或DFS),广度优先搜索,总结前边介绍了有关图的 4 种存储方式,本节介绍如何对存储的图中的顶点进行遍历。常用的遍历方式有两种: 深度优先搜索和 广度优先搜索。 深度优先搜索(简称“深搜”或DFS) 图 1 无向图 深度优先搜索的过程类似于树的先序遍历,首先从例子中体会深度优先搜索。例如图 1 是一个无向图,采用深度优先算法遍历这个图的过程为: 首先任意找一个未被遍历过的顶点,例如从 V1 开始,由于 V1 率先访问过了,所以

  • 我正在研究BFS算法,我有一个关于如何将相邻节点插入队列的问题。 例如,假设我们正在处理一个无向图,我们希望执行BFS来输出图的内容,那么我们如何知道在从队列中取出一个初始节点后,相邻节点以什么顺序插入到队列中呢?还有,有没有办法修改邻居节点插入队列的方式? 任何帮助都将不胜感激,谢谢。

  • 在有向图上进行广度优先搜索时,我很难找到一种正确分类边的方法。 在广度优先或深度优先搜索过程中,可以将遇到的边缘分为4类: 树 后退 交叉 转发 但普通循环不起作用: 当最后交叉边eCA时,处理并发现A。所以这个边被错误地标注为十字,是否应该是一个后边。 这两种情况的处理方式确实没有区别,即使这两种边缘有不同的类别。

  • 首先感谢大家看这个问题。 对于学校作业,我们应该创建一个BFS算法,并用它来做各种事情。其中一件事是,我们应该找到图的根节点和目标节点之间的所有路径。我不知道如何做到这一点,因为我找不到一种方法来跟踪所有备用路线,同时不包括副本/周期。 这是我的BFS代码: 如果能在概念上朝着正确的方向推进,将会受到极大的赞赏。 tl;dr 如何使用 BFS 查找两个节点之间的所有路径? 这是图表,因为我不知道如

  • 本文向大家介绍什么是广度优先搜索?相关面试题,主要包含被问及什么是广度优先搜索?时的应答技巧和注意事项,需要的朋友参考一下 类似树的按层遍历,其过程为:首先访问初始点Vi,并将其标记为已访问过,接着访问Vi的所有未被访问过可到达的邻接点Vi1、Vi2……Vit,并均标记为已访问过,然后再按照Vi1、Vi2……Vit的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依此类推,直到图

  • 在继续使用其他图算法之前,让我们分析广度优先搜索算法的运行时性能。首先要观察的是,对于图中的每个顶点 $$|V|$$ 最多执行一次 while 循环。因为一个顶点必须是白色,才能被检查和添加到队列。这给出了用于 while 循环的 $$O(V)$$。嵌套在 while 内部的 for 循环对于图中的每个边执行最多一次,$$|E|$$。原因是每个顶点最多被出列一次,并且仅当节点 u 出队时,我们才检