• 广度优先遍历详解


    前言

    广度优先搜索不同于深度优先搜索,它是一层层进行遍历的,因此需要先入先出的队列而非先入后出的栈进行遍历。由于是按层次进行遍历,广度优先搜索时按照“广”的方向进行遍历的

    一、工作原理

    我们构造这样一个图(如图1),并通过C++实现BFS,本文处理的图比二叉树要更复杂,如果时针对二叉树的BFS,程序会更为简单

    算法过程:

    1.将根节点放入队列中

    2.从队列中取出第一个元素,将队列中的第一个元素弹出

    3.将所取得元素的全部节点加入队列中

    4.判断队列是否为空

         a. 若是,则结束

         b.若不是,则跳到第二步

    二、模板

    由于是二维矩阵,需要q队列需要存储(x, y),所以需要定义结构体node

    1. struct node
    2. {
    3. int x;
    4. int y;
    5. };

    为了减少推入队列的繁琐操作太多可以写一个函数循环利用

    1. void p(int x, int y)
    2. {
    3. node tmp;
    4. tmp.x = x;
    5. tmp.y = y;
    6. q.push(tmp);
    7. }

    函数模板

    1. void bfs()
    2. {
    3. //将起点推入队列
    4. while(!q.empty()) //保证队列不为空
    5. {
    6. node xy; //队列的定义是node类型,推进队列也要是node类型的!
    7. xy = q.front(); //拿走队头元素
    8. q.pop(); //细节出队
    9. if(判断是否为终点或其他出口)
    10. {
    11. 退出等其他操作
    12. }
    13. for(int i = 101都行); i <= (4个或8个方向); i++)
    14. {
    15. int nx = xy.x + dx[i];//确定下一步的位置
    16. int ny = xy.y + dy[i];
    17. //出界与访问的判断
    18. if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && !vis[nx][ny] && 其他判断条件)
    19. {
    20. vis[nx][ny] = true; //将新的点标记
    21. p(nx, ny) //nx, ny推进队列
    22. }
    23. }
    24. }
    25. }

    三、主要应用

    (一)最短路径问题

    题目描述

    小明置身于一个迷宫,请你帮小明找出从起点到终点的最短路程。小明只能向上下左右四个方向移动。

    输入格式

    输入包含多组测试数据。输入的第一行是一个整数T,表示有T组测试数据。 每组输入的第一行是两个整数N和M(1<=N,M<=100)。 接下来N行,每行输入M个字符,每个字符表示迷宫中的一个小方格。 字符的含义如下: ‘S’:起点 ‘E’:终点 ‘-’:空地,可以通过 ‘#’:障碍,无法通过 输入数据保证有且仅有一个起点和终点。

    输出格式

    对于每组输入,输出从起点到终点的最短路程,如果不存在从起点到终点的路,则输出-1。

    样例输入

    1. 1
    2. 5 5
    3. S-###
    4. -----
    5. ##---
    6. E#---

    样例输出

    9

    参考代码

    1. #include
    2. #include
    3. #include
    4. #include
    5. #define ll long long
    6. using namespace std;
    7. struct node
    8. {
    9. int x;
    10. int y;
    11. };
    12. char a[105][105];
    13. int vis[105][105], flag = false;
    14. int dx[5] = {0, -1, 1, 0, 0};
    15. int dy[5] = {0, 0, 0, -1, 1};
    16. int n, m, sx, sy, cnt = 0, maxx = 0;
    17. queue q;
    18. void p(int x, int y)
    19. {
    20. node tmp;
    21. tmp.x = x;
    22. tmp.y = y;
    23. q.push(tmp);
    24. }
    25. void bfs()
    26. {
    27. p(sx, sy);
    28. while(!q.empty())
    29. {
    30. node xy;
    31. xy = q.front();
    32. q.pop();
    33. if(a[xy.x][xy.y] == 'E')
    34. {
    35. cout<
    36. flag = true;
    37. return;
    38. }
    39. for(int i = 1; i <= 4; i++)
    40. {
    41. int nx = xy.x + dx[i];
    42. int ny = xy.y + dy[i];
    43. if(nx >= 1 && nx <= n && ny >= 1 && ny <= m && vis[nx][ny] == 0 && (a[nx][ny] == 'E' || a[nx][ny] == '-'))
    44. {
    45. vis[nx][ny] = vis[xy.x][xy.y] + 1;
    46. p(nx, ny);
    47. }
    48. }
    49. }
    50. }
    51. int main()
    52. {
    53. int t;
    54. cin>>t;
    55. for(int v = 1; v <= t; v++)
    56. {
    57. cin>>n>>m;
    58. memset(a, '#', sizeof(a));
    59. memset(vis, 0, sizeof(vis));
    60. for(int i = 1; i <= n; i++)
    61. {
    62. for(int j = 1; j <= m; j++)
    63. {
    64. cin>>a[i][j];
    65. if(a[i][j] == 'S')
    66. {
    67. sx = i;
    68. sy = j;
    69. }
    70. }
    71. }
    72. bfs();
    73. if(!flag)
    74. cout<<-1<
    75. flag = false;
    76. }
    77. return 0;
    78. }

    好了,本期文章就到这里,喜欢的老铁可以给我点个小爱心鼓励一下我,你们的鼓励是我最大的动力!

    你觉得这样辛苦的写博文不值得你点赞吗?

  • 相关阅读:
    Git 行结束符:LF will be replaced by CRLF the next time Git touches it问题解决指南
    挑战杯 基于深度学习的人脸表情识别
    abaqus Isight学习
    连接本地mysql容器
    使用itextPDF实现PDF电子公章工具类
    使用cpolar发布树莓派网页(apache2网页的发布)
    vue/自定义指令
    刷题记录:牛客NC20471[ZJOI2007]棋盘制作
    oracle OCP OCM MySQL OCP认证难吗?
    香橙派硬件PWM控制sg90舵机
  • 原文地址:https://blog.csdn.net/panpanpan17452/article/details/133776524