C++实现广度优先遍历图

本文实例为大家分享了C++实现广度优先遍历图的具体代码,供大家参考,具体内容如下

广度优先遍历

void bfs(int start, int parent[], int dist[], int seen[], int visited[]) {
    std::queue <int> q;//建立数据队列q
    int v;

    q.push(start);    //让开始序列入栈
    parent[start] = start;      // 开始节点的父节点是开始节点
    dist[start] = 0;            // 初始化距离向量为-1
    seen[start] = 1;       

    while(!q.empty()) {         //如果队列非空
        v = q.front(); q.pop();   //令V是队列的最前端,并将其出栈
        if(visited[v])          // 如果visited[v]=1, continue.
            continue;
        visited[v] = 1;         //否则令visited[v]=1
        std::cout << v << '\n';//输出显示当前节点

        // 遍历v的所有相邻节点
        for(int i = 0; i < graph[v].size(); i++) {
            // 如果v的第i个相邻节点的i并没有访问过
            if(!visited[graph[v][i]]) {

                // 如果这个没有访问过的节点没有被看过
                if(!seen[graph[v][i]]) {
                //压入栈,距离+1,设置父节点
                    q.push(graph[v][i]);
                    dist[graph[v][i]] = 1 + dist[v];
                    parent[graph[v][i]] = v;
                    // 如果已经访问过,令seen=1.
                    seen[graph[v][i]] = 1;
                }
            }
            else {

                // 如果节点已经被访问了,选择距离最小的
                if(dist[v] + 1 < dist[graph[v][i]]) {
                    dist[graph[v][i]] = 1 + dist[graph[v][i]];
                    parent[graph[v][i]] = v;
                }
            }
        }
    }
}

主函数

int main() {

    int n = 8;          // 图中的节点数
    graph = std::vector <std::vector <int> > (n);

    // 图的邻接表
    graph[0] = {1, 2};
    graph[1] = {0, 2, 3};
    graph[2] = {0, 1, 5, 6};
    graph[3] = {1, 2, 4};
    graph[4] = {3};
    graph[5] = {2};
    graph[6] = {2, 7};
    graph[7] = {6};

    /* - parent[i] = parent of 'i' in BFS traversal.
       - dist[i] = 从开始到I节点的最短距离shortest distance of 'i' from 'start'.
       - If seen[i] == 1, 节点i已经进入过队列'i' has entered the queue once
       - If visited[i] == 1, 节点i已经进入队列,并且所有相邻节点都已经进入过队列
    */
    int parent[n+1], dist[n+1], seen[n+1], visited[n+1];
    memset(parent, -1, sizeof(parent));//父节点初始化为-1
    memset(dist, -1, sizeof(dist));//距离向量初始化为-1
    memset(seen, 0, sizeof(seen));
    memset(visited, 0, sizeof(visited));//seen用于判断该节点是否访问过

    int start = 0;      // 开始节点
    bfs(start, parent, dist, seen, visited);

    return 0;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 用C++的odeint库求解微分方程

    目录 1.集成方程 2.求解单摆模型 2.1 微分方程标准化 2.2 代码实现 微分方程的标准形式为: 即:\dot{\boldsymbol{x}} = \boldsymbol{f}(\boldsymbol{x}, t),\, \boldsymbol{x}(0) = \boldsymbol{x_0} 这是一阶微分方程组, \boldsymbol{x} 和 \boldsymbol{f}(\boldsymbol{x}, t) 均为向量.如果要求解高阶微分方程,需要先转换成一阶微分方程组后再用odei

  • C++ 标准模板类详解

    目录 1 标准模板库 2.泛型编程 总结 1 标准模板库 STL提供了表示容器.迭代器.函数对象和算法的模板. 容器:类似数组存储若干值,切实同质的: 迭代器:遍历容器的对象,类似遍历数组的指针,广义指针: 算法:完成特定的任务: 函数对象:类对象或函数指针. 模板类 vector erase() 删除矢量中给定区间元素.接受两个迭代器参数(该参数定义了要删除的区间),迭代器1指向区间起始处,迭代器2指向区间终止处的后一个位置. // delete first and second elemen

  • C++的命名空间详解

    目录 C++ | C++命名空间 C++命名空间 定义命名空间 实例1: using 指令 实例2: 实例3: 不连续的命名空间 嵌套的命名空间 实例4: 实例5: 笔记: 实例6: 实例7: 总结 C++ | C++命名空间 C++命名空间 一个中大型软件往往由多名程序员共同开发,会使用大量的变量和函数,不可避免地会出现变量或函数的命名冲突. 当所有人的代码都测试通过,没有问题时,将它们结合到一起就有可能会出现命名冲突. 例如小李和小韩都参与了一个文件管理系统的开发,它们都定义了一个全局变量

  • C++实现矩阵对称正交化的示例代码

    1.python代码 import numpy as np import pandas as pd df=pd.DataFrame() df['fac_01']=(34, 45, 65) df['fac_02']=(56, 25, 94) print(df) print('------------------矩阵的特征跟D.和特征向量U-----------------------') D,U=np.linalg.eig(np.dot(df.T, df)) # 求矩阵的特征跟D.和特征向量U p

  • C++类的特种函数生成机制详解

    目录 C++类的特种函数生成机制 规则 例子:A BUG 例子:std::mutex和std::thread 题外话:为什么std::mutex不可移动? 总结 C++类的特种函数生成机制 规则 参考Effective Morder C++上的说明: 默认构造函数:仅当类中不包含用户声明的构造函数时才生成. 析构函数:默认生成,当基类的析构函数为虚时,派生类的默认析构函数为虚函数. 拷贝构造函数:仅当类中不包含用户声明的拷贝构造函数时才生成.如果该类声明了移动操作,那么拷贝构造函数将被定义为删除

  • C++的异常处理一篇带你了解

    目录 一.背景 二.C++ 异常处理 三.抛出异常与捕获异常 四.catch(...)的作用 总结 一.背景 程序运行时常会碰到一些异常情况,例如: 做除法的时候除数为 0: 用 new 运算符动态分配空间时,空间不够导致无法分配: 访问数组元素时,下标越界:打开文件读取时,文件不存在. 这些异常情况,如果不能发现并加以处理,很可能会导致程序崩溃. 所谓"处理",可以是给出错误提示信息,然后让程序沿一条不会出错的路径继续执行:也可能是不得不结束程序,但在结束前做一些必要的工作,如将内存

  • C++实现对象化的矩阵相乘小程序

    复习数学1的线性代数,矩阵相乘这块有点晕,想编个C++对象化的矩阵相乘小程序. 相乘部分 void sum(juzhen a, juzhen b, juzhen &c) { int s=0; for (int i = 1; i <= a.m1(); i++)//A矩阵的M for (int j = 1; j <= b.n1(); j++)//B矩阵的S { for (k0 = 1; k0 <= a.n1(); k0++)//a.n1也就是b.m1(a的n,b的n)[行向量*列向量

  • C++基于OpenCV实现手势识别的源码

    先给大家上效果图: 源码在下面 使用 RGB 值分割手部区域,即手部的 GB 值将与背景不同 或者使用边缘检测 或者 背景减法. 我这里使用了背景减法模型.OpenCV为我们提供了不同的背景减法模型,codebook   它的作用是对某些帧进行一段时间的精确校准.其中对于它获取的所有图像:它计算每个像素的平均值和偏差,并相应地指定框. 在前景中它就像一个黑白图像,只有手是白色的 用 Convex Hull 来找到指尖.Convex hull 基本上是包围手部区域的凸集. 包围手的红线是凸包.基本

  • 浅谈C++ 设计模式的基本原则

    先上银行类案例代码如下: #include<iostream> using namespace std; class BankWorker { public: void save() { cout << "存款" << endl; } void moveM() { cout << "取款" << endl; } void jiaofei() { cout << "缴费" &l

  • C++中的构造函数详解

    目录 普通变量的初始化 构造函数 一定会生成默认构造函数吗? 防止隐式类型转换 赋值与初始化的区别 对象的计数 成员初始化的顺序 类的引用成员 构造函数使用注意事项 参考 总结 普通变量的初始化 当我们在定义一个变量不给它指定一个初始值时,这对于全局变量和局部变量来说结果会不一样.全局变量在程序装入内存时 就已经分配好空间,程序运行期间其地址不变,它会被初始化为全0(变量的每一位都为0).但是局部变量定义在函数内部,存储在栈上,当函数被调用时,栈会分配一部分空间来存储该局部变量(也就是只分配空间

随机推荐