迷宫问题 - 队列与广度优先搜索

队列也是一组元素的集合,也提供两种基本操作:Enqueue(入队)将元素添加到队尾,Dequeue(出队)从队头取出元素并返回。就像排队买票一样,先来先服务,先入队的人也是先出队的,这种方式称为FIFO(First In First Out,先进先出),有时候队列本身也被称为FIFO。

下面我们用队列解决迷宫问题。程序如下:(参考《linux c 编程一站式学习》)

C++ Code


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

 
/*************************************************************************

> File Name: breadth_search.c

> Author: Simba

> Mail: [email protected]

> Created Time: 2012年12月24日 星期一 19时24分37秒

************************************************************************/

#include<stdio.h>

#define MAX_ROW 5

#define MAX_COL 5

struct point

{

int row, col, predecessor;

} queue[512];

int head = 0, tail = 0;

void enqueue(struct point p)

{

queue[tail++] = p;

}

struct point dequeue(void)

{

return queue[head++];

}

int is_empty(void)

{

return head == tail;

}

int maze[MAX_ROW][MAX_COL] =

{

{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},

};

void print_maze(void)

{

int i, j;

for (i = 0; i < MAX_ROW; i++)

{

for (j = 0; j < MAX_COL; j++)

printf("%d ", maze[i][j]);

putchar(‘\n‘);

}

printf("*********\n");

}

void visit(int row, int col)

{

struct point visit_point = { row, col, head - 1 };

maze[row][col] = 2;

enqueue(visit_point);

}

int main(void)

{

struct point p = { 0, 0, -1 };

maze[p.row][p.col] = 2;

enqueue(p);

while (!is_empty())

{

p = dequeue();

if (p.row == MAX_ROW - 1    /* goal */

&& p.col == MAX_COL - 1)

break;

if (p.col + 1 < MAX_COL /* right */

&& maze[p.row][p.col + 1] == 0)

visit(p.row, p.col + 1);

if (p.row + 1 < MAX_ROW /* down */

&& maze[p.row + 1][p.col] == 0)

visit(p.row + 1, p.col);

if (p.col - 1 >= 0  /* left */

&& maze[p.row][p.col - 1] == 0)

visit(p.row, p.col - 1);

if (p.row - 1 >= 0  /* up */

&& maze[p.row - 1][p.col] == 0)

visit(p.row - 1, p.col);

print_maze();

}

if (p.row == MAX_ROW - 1 && p.col == MAX_COL - 1)

{

printf("(%d, %d)\n", p.row, p.col);

while (p.predecessor != -1)

{

p = queue[p.predecessor];

printf("(%d, %d)\n", p.row, p.col);

}

}

else

printf("No path!\n");

return 0;

}

输出为:

其实仍然可以像《用深度优先搜索解迷宫问题》一样用predecessor数组表示每个点的前趋,但我们可以换一种更方便的数据结构,直接在每个点的结构体中加一个成员表示前趋:

struct point { int row, col, predecessor; } queue[512];

int head = 0, tail = 0;

变量head和tail是队头和队尾指针,head总是指向队头,tail总是指向队尾的下一个元素。每个点的predecessor成员也是一个指针,指向它的前趋在queue数组中的位置。如下图所示:

这是一个静态分配的数组,每个数组元素都有row、col和predecessor三个成员,predecessor成员保存一个数组下标,指向数组中的另一个元素,这其实也是链表的一种形式,称为《静态链表》。

为了帮助理解,把这个算法改写成伪代码如下图:

从打印的搜索过程可以看出,这个算法的特点是沿各个方向同时展开搜索,每个可以走通的方向轮流往前走一步,这称为广度优先搜索(BFS,Breadth First Search)。探索迷宫和队列变化的过程如下图所示。

广度优先是一种步步为营的策略,每次都从各个方向探索一步,将前线推进一步,图中的虚线就表示这个前线,队列中的元素总是由前线的点组成的,可见正是队列先进先出的性质使这个算法具有了广度优先的特点。广度优先搜索还有一个特点是可以找到从起点到终点的最短路径,而深度优先搜索找到的不一定是最短路径。

原文地址:https://www.cnblogs.com/alantu2018/p/8471672.html

时间: 2024-11-09 19:10:12

迷宫问题 - 队列与广度优先搜索的相关文章

leetcode_226题——Invert Binary Tree(队列,广度优先搜索)

Invert Binary Tree Total Accepted: 22352 Total Submissions: 62065My Submissions Question Solution Invert a binary tree. 4 / 2 7 / \ / 1 3 6 9 to 4 / 7 2 / \ / 9 6 3 1 Trivia:This problem was inspired by this original tweet by Max Howell: Google: 90%

深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现

1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点)开始,沿着铁轨(边)移动到其他城市(顶点),有两种方法可以用来搜索图:深度优先搜索(DFS)和广度优先搜索(BFS).它们最终都会到达所有连通的顶点,深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现,不同的实现机制导致不同的搜索方式. 1.1 深度优先搜索 深度优先搜索算法有如下规则: 规则1

基于深度及广度优先搜索的迷宫问题的演示

1 时间复杂度分析 由于该图采用邻接矩阵存储,整个算法遍历的过程所花费的时间复杂度为该矩阵的N(row*col).而由于其需要分别访问已经定位,需要进行分别2次操作,如下: visited = new bool[col*row];//访问标记 for (i=0; i<row; i++) for (j=0; j<col; j++) visited[i*col+j] = false;//初始为未访问状态 position = new POSITION[col*row]; for (i=0; i&l

迷宫问题(maze problem)——深度优先(DFS)与广度优先搜索(BFS)求解

1.问题简介 给定一个迷宫,指明起点和终点,找出从起点出发到终点的有效可行路径,就是迷宫问题(maze problem). 迷宫可以以二维数组来存储表示.0表示通路,1表示障碍.注意这里规定移动可以从上.下.左.右四方方向移动.坐标以行和列表示,均从0开始,给定起点(0,0)和终点(4,4),迷宫表示如下: int maze[5][5]={ {0,0,0,0,0}, {0,1,0,1,0}, {0,1,1,0,0}, {0,1,1,0,1}, {0,0,0,0,0} }; 那么下面的迷宫就有两条

广度优先搜索[再解迷宫]

上一节讲过深度优先搜索解决迷宫,http://blog.csdn.net/wtyvhreal/article/details/43268115 这一节讲解广度优先搜索解决迷宫. 广度优先搜索(Breadth First Search,BFS),也称为宽度优先搜索. 还是二维数组存储,开始小哼在(1,1)处,在深搜里我们先让小哼往右边走,然后一直尝试下去,直到走不通的时候再回到这里.这样是深搜,可以通过函数递归实现.广搜的方法:通过一层一层扩展的方法找到小哈.扩张的时候每发现一个点就将这个点加入到

迷宫问题的求解(广度优先搜索)

     迷宫问题很容易可以理解为广度优先搜索问题,站在一个点上,首先试一试自己周围的点是否可以走,如果是路则加入待走队列,如果是墙则丢弃.迷宫问题在广度优先搜索的时候需要特别注意的就是要及时抛弃,遇到走过的点立即丢弃,遇到墙立即丢弃,不然时间复杂度就很高.    题目描述 Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城

ybt 1252 广度优先搜索 走迷宫(二维、最小步数)

1252:走迷宫 时间限制: 1000 ms         内存限制: 65536 KB提交数: 7272     通过数: 3241 [题目描述] 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走:有的格子是空地,可以走. 给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到).只能在水平方向或垂直方向走,不能斜着走. [输入] 第一行是两个整数,R和C,代表迷宫的长和宽.( 1≤ R,C ≤ 40) 接下来是R行,每行C个字符,代表整个迷宫. 空地格子用‘.’表示,

leetcode_199题——Binary Tree Right Side View(广度优先搜索,队列queue)

#include<iostream> #include<queue> #include<vector> using namespace std; // Definition for binary tree struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; /*这道题采用广度优先搜索的算法来做

Catch The Caw——(广度优先搜索的应用,队列)

抓住那头牛(POJ3278)农夫知道一头牛的位置,想要抓住它.农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000).农夫有两种移动方式:1.从X移动到X-1或X+1,每次移动花费一分钟2.从X移动到2*X,每次移动花费一分钟假设牛没有意识到农夫的行动,站在原地不动.农夫最少要花多少时间才能抓住牛? 广搜算法?广度优先搜索算法如下:(用QUEUE)(1) 把初始节点S0放入Open表中:(2) 如果Open表为空,则问题无解,失败