这个算法,用邻接矩阵表示迷宫,主要的思路是:从起点出发,寻找可以走的位置,将横纵坐标压入栈中,当走入死胡同时,读取栈中的横纵坐标,标记该位置,避免再次进入死胡同中,然后再寻找其他的路线,直到找到出口。
这种一步步回退的技巧叫做回溯,回溯的基本原理是从某一个点开始,找不到解时(在迷宫中,就是进入了死胡同),就回到前一个结点,再次重新从这个点出发尝试下一个未尝试的可能路径。
下面是代码实现:
# include <stdio.h>
# include <stdlib.h>
# define LIST struct list
typedef struct //四个方向的结点
{
int vert;
int horiz;
}offsets;
typedef LIST //入栈的结点
{
int line;
int colu;
LIST *next;
}link;
LIST *put(int x, int y, LIST *p) //入栈函数
{
LIST *p1, *p2;
p1 = (LIST *)malloc(sizeof(LIST));
p1->line = x;
p1->colu = y;
p2 = p;
p1->next = p2;
p = p1;
return p;
}
LIST *dele(LIST *p) //出栈函数
{
LIST *p1;
p1 = p;
p = p->next;
free(p1);
return p;
}
int main()
{
void work_maze(int maze[][10], int line, int colu, offsets move[4]);
offsets move[4]; //定义结构体数组,分别是上下左右四个方向的。
move[0].vert = -1; move[0].horiz = 0;
move[1].vert = 1; move[1].horiz = 0;
move[2].vert = 0; move[2].horiz = -1;
move[3].vert = 0; move[3].horiz = 1;
int maze[10][10] = {{1,1,1,1,1,1,1,1,1,1},{2,0,1,1,1,0,1,0,1,1},{1,0,0,1,0,0,0,1,0,1},
{1,0,1,1,0,1,0,1,0,2},{1,0,0,0,0,1,0,1,0,1},{1,1,1,0,1,1,0,1,0,1},{1,1,0,1,1,1,0,0,0,1},
{1,0,1,1,0,0,1,1,0,1},{1,0,0,1,1,0,0,1,0,1},{1,1,1,1,1,1,1,1,1,1}}; //迷宫用邻接矩阵表示
int line = 3, colu = 8;
int i, j;
work_maze(maze, line, colu, move);
for(i = 0; i < 10; i++) //打印迷宫以及路线
{
for(j = 0; j < 10; j++)
{
if(maze[i][j] == 1)
printf("■");
else if(maze[i][j] == 2)
printf("%2c", 16);
else if(maze[i][j] == 3)
printf("%2c", 17);
else if(maze[i][j] == 4)
printf("%2c", 31);
else if(maze[i][j] == 5)
printf("%2c", 30);
else
printf(" ");
}
printf("\n");
}
printf("\n");
return 0;
}
void work_maze(int maze[][10], int line, int colu, offsets move[4])
{
int line1, colu1, d = 0, found = 0, m, n, flag = 0;
LIST *top, *p;
top = NULL;
line1 = 1; colu1 = 1; maze[line1][colu1] = 2;
p = (LIST *)malloc(sizeof(LIST));
p->line = line1;
p->colu = colu1;
p->next = top;
top = p;
while(found == 0)
{
if(flag != 0 && top == p) //表示没有出口
{
printf("无路可走!!\n");
break;
}
else if(flag != 0)
{ //读栈
maze[line1][colu1] = -1; //标记为-1,表示为已经走过的,且是走不通的路!
line1 = top->next->line;
colu1 = top->next->colu;
top = dele(top); //栈顶的出栈
}
while(d < 4)
{
m = line1 + move[d].vert;
n = colu1 + move[d].horiz;
if(maze[m][n] == 0)
{
line1 = m; colu1 = n;
top = put(line1, colu1, top); //将走到的位置压入栈
if(d == 0) //标记路线
maze[line1][colu1] = 5;
else if(d == 1)
maze[line1][colu1] = 4;
else if(d == 2)
maze[line1][colu1] = 3;
else if(d == 3)
maze[line1][colu1] = 2;
flag = 1;
if(line1 == line && colu1 == colu) //表示找到了出口
{
found = 1;
break;
}
else
{
d = 0; //找到有路,d重新赋值0
}
}
else
{
d++; //尝试其他方向
}
}
d = 0;
}
}
下面是样例结果:
用栈模拟深度优先,在这个算法中,需要注意的是路径的标记。!~~~