当前位置:   article > 正文

宽度优先搜索

宽度优先搜索
宽度优先搜索(又称广度优先搜索,简称BFS),一种先生成的节点,先扩展的策略。 搜索过程:从初始节点开始逐层向下扩展,在第n层节点还没搜索结束之前,不能进入第n+1层搜索(需要使用队列实现) (1) 把初始节点放入到队列中 (2) 如果队列为空,则问题无解,跳出循环 (3) 取出队列中的第一个元素,并记该节点为cur,并将队列第一个元素删除 (4) 考察cur节点是否为目标节点,如果是目标节点则问题解决,跳出循环 (5) 若节点cur不能扩展则跳到第二步; (6) 若节点cur可以扩展,将其子节点放入队列的尾部,跳到第二步 例题:走迷宫问题 给定一个二维数组 int map[5][5] = { 0 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , } ; 它表示一个迷宫,其中“1”表示墙壁,“0”表示可以走的路,只能横着走或者竖着走,不能斜着走,要求编写程序求出从左上角到右下角的最短路径的长度,例如上述问题输出结果为:8
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. using namespace std ;
  7. int a[100][100] , vis[100][100] = {0} ;
  8. int m , n ;
  9. struct dot{
  10. int x ;
  11. int y ;
  12. int step ;
  13. };
  14. int dx[] = {-1,0,1,0} ;
  15. int dy[] = {0,1,0,-1} ;
  16. bool is_ok(dot cur) {
  17. if(cur.x < 0|| cur.x >= m || cur.y < 0 || cur.y >= n )
  18. return 0 ;
  19. return 1 ;
  20. }
  21. int bfs() {
  22. dot A ;
  23. A.x = 0 ;
  24. A.y = 0 ;
  25. A.step = 0 ;
  26. vis[0][0] = 1 ;
  27. queue q ;
  28. while(!q.empty())
  29. q.pop() ;
  30. q.push(A) ;
  31. while(!q.empty()) {
  32. dot cur = q.front() ;
  33. q.pop();
  34. if(cur.x == m-1 && cur.y == n-1)
  35. return cur.step ;
  36. dot next ;
  37. for(int i = 0 ; i < 4 ; i++) {
  38. next.x = cur.x + dx[i] ;
  39. next.y = cur.y + dy[i] ;
  40. next.step = cur.step + 1 ;
  41. if(is_ok(next)&&a[next.x][next.y] != 1&&vis[next.x][next.y] != 1) {
  42. q.push(next) ;
  43. vis[next.x][next.y] = 1 ;
  44. }
  45. }
  46. }
  47. return 0 ;
  48. }
  49. int main() {
  50. scanf("%d%d",&m,&n) ;
  51. int i , j , k ;
  52. for(i = 0 ; i < m ; i++)
  53. for(j = 0 ; j < n ; j++)
  54. scanf("%d",&a[i][j]) ;
  55. int step = bfs() ;
  56. printf("%d\n",step) ;
  57. return 0 ;
  58. }
当节点足够多时,有可能会超出队列的容量,程序在运行时就会出错,所以也可以使用数组代替队列。
  1. #include
  2. #include
  3. #include
  4. #include
  5. using namespace std ;
  6. int a[100][100] , vis[100][100] = {0} ;
  7. int m , n ;
  8. struct dot{
  9. int x ;
  10. int y ;
  11. int step ;
  12. }d[10000];
  13. int dx[] = {-1,0,1,0} ;
  14. int dy[] = {0,1,0,-1} ;
  15. bool is_ok(dot cur) {
  16. if(cur.x < 0|| cur.x >= m || cur.y < 0 || cur.y >= n )
  17. return 0 ;
  18. return 1 ;
  19. }
  20. int bfs() {
  21. dot A ;
  22. A.x = 0 ;
  23. A.y = 0 ;
  24. A.step = 0 ;
  25. vis[0][0] = 1 ;
  26. int head = 0 , tail = 0 ;
  27. d[tail++] = A ;
  28. while(head < tail) {
  29. dot cur = d[head++] ;
  30. if(cur.x == m-1 && cur.y == n-1)
  31. return cur.step ;
  32. dot next ;
  33. for(int i = 0 ; i < 4 ; i++) {
  34. next.x = cur.x + dx[i] ;
  35. next.y = cur.y + dy[i] ;
  36. next.step = cur.step + 1 ;
  37. if(is_ok(next)&&a[next.x][next.y] != 1&&vis[next.x][next.y] != 1) {
  38. d[tail++] = next ; ;
  39. vis[next.x][next.y] = 1 ;
  40. }
  41. }
  42. }
  43. return 0 ;
  44. }
  45. int main() {
  46. scanf("%d%d",&m,&n) ;
  47. int i , j , k ;
  48. for(i = 0 ; i < m ; i++)
  49. for(j = 0 ; j < n ; j++)
  50. scanf("%d",&a[i][j]) ;
  51. int step = bfs() ;
  52. printf("%d\n",step) ;
  53. return 0 ;
  54. }
如果想输出所走的路径,可以先记录各个节点的父节点位置,然后递归输出路径:
  1. #include
  2. #include
  3. #include
  4. #include
  5. using namespace std ;
  6. int a[100][100] , vis[100][100] = {0} ;
  7. int m , n ;
  8. struct dot{
  9. int x ;
  10. int y ;
  11. int step ;
  12. }d[10000];
  13. int pre[10000] ;
  14. int dx[] = {-1,0,1,0} ;
  15. int dy[] = {0,1,0,-1} ;
  16. bool is_ok(dot cur) {
  17. if(cur.x < 0|| cur.x >= m || cur.y < 0 || cur.y >= n )
  18. return 0 ;
  19. return 1 ;
  20. }
  21. void print(int x) { //递归输出
  22. int t = pre[x] ;
  23. if(t == 0) {
  24. printf("(0,0)\n") ; //先输出父节点位置
  25. printf("(%d,%d)\n" ,d[x].x , d[x].y) ; //再输出本身位置
  26. return ;
  27. }
  28. print(t) ; //先输出父节点位置
  29. printf("(%d,%d)\n" ,d[x].x , d[x].y) ; //再输出本身位置
  30. }
  31. int bfs() {
  32. dot A ;
  33. A.x = 0 ;
  34. A.y = 0 ;
  35. A.step = 0 ;
  36. vis[0][0] = 1 ;
  37. int head = 0 , tail = 0 ;
  38. d[tail++] = A ;
  39. while(head < tail) {
  40. dot cur = d[head++] ;
  41. if(cur.x == m-1 && cur.y == n-1) {
  42. print(head-1) ;
  43. return cur.step ;
  44. }
  45. dot next ;
  46. for(int i = 0 ; i < 4 ; i++) {
  47. next.x = cur.x + dx[i] ;
  48. next.y = cur.y + dy[i] ;
  49. next.step = cur.step + 1 ;
  50. if(is_ok(next)&&a[next.x][next.y] != 1&&vis[next.x][next.y] != 1) {
  51. pre[tail] = head - 1 ; //记录该节点的父节点所在位置
  52. d[tail++] = next ; ;
  53. vis[next.x][next.y] = 1 ;
  54. }
  55. }
  56. }
  57. return 0 ;
  58. }
  59. int main() {
  60. scanf("%d%d",&m,&n) ;
  61. int i , j , k ;
  62. for(i = 0 ; i < m ; i++)
  63. for(j = 0 ; j < n ; j++)
  64. scanf("%d",&a[i][j]) ;
  65. int step = bfs() ;
  66. printf("%d\n",step) ;
  67. return 0 ;
  68. }

转载于:https://www.cnblogs.com/NYNU-ACM/p/4236847.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/386119
推荐阅读
相关标签
  

闽ICP备14008679号