迷宫:
对于一个用空格和‘#’号组成的迷宫,如下:
{’#’,’#’,’#’,’#’,’#’,’#’,’#’,’#’,’#’,’#’},
{’#’,’ ‘,’ ‘,’#’,’ ‘,’ ‘,’ ‘,’#’,’ ‘,’#’},
{’#’,’ ‘,’ ‘,’#’,’ ‘,’ ‘,’ ‘,’#’,’ ‘,’#’},
{’#’,’ ‘,’ ‘,’ ‘,’ ‘,’#’,’#’,’ ‘,’ ‘,’#’},
{’#’,’ ‘,’#’,’#’,’#’,’ ‘,’ ‘,’ ‘,’ ‘,’#’},
{’#’,’ ‘,’ ‘,’ ‘,’#’,’ ‘,’ ‘,’ ‘,’ ‘,’#’},
{’#’,’ ‘,’#’,’ ‘,’ ‘,’ ‘,’#’,’ ‘,’ ‘,’#’},
{’#’,’ ‘,’#’,’#’,’#’,’ ‘,’#’,’#’,’ ‘,’#’},
{’#’,’#’,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,‘0’,’#’},
{’#’,’#’,’#’,’#’,’#’,’#’,’#’,’#’,’#’,’#’};
这是一个10*10的迷宫。
如果碰到‘#’,那个方向就走不通。
大致算法
递归:
初始点为(1,1),优先向右探路,不通就向下,还不通的就向左,再不通就向上探路。
栈
每走一步,判断是否走过,如果没有,就把坐标记录到栈中。如果有,返回上一层递归。
#include"stdio.h"
#include"stdlib.h"
typedef struct Position
{
int row;
int column;
struct Position *next;
}*link,node;
link stack;
int book[10][10] = { 0 };//定义一个数组用于标记,若该点走过,则置为1
//定义地图
char MAP[10][10] =
{ {'#','#','#','#','#','#','#','#','#','#'},
{'#',' ',' ','#',' ',' ',' ','#',' ','#'},
{'#',' ',' ','#',' ',' ',' ','#',' ','#'},
{'#',' ',' ',' ',' ','#','#',' ',' ','#'},
{'#',' ','#','#','#',' ',' ',' ',' ','#'},
{'#',' ',' ',' ','#',' ',' ',' ',' ','#'},
{'#',' ','#',' ',' ',' ','#',' ',' ','#'},
{'#',' ','#','#','#',' ','#','#',' ','#'},
{'#','#',' ',' ',' ',' ',' ',' ','0','#'},
{'#','#','#','#','#','#','#','#','#','#'}, };
void printMap();
int pop_print();
void pop();
void push(int , int );
int search(int ,int);
int main()
{
stack = (link)malloc(sizeof(node));//初始化用来存储路径的栈
stack->row = 0;
stack->column = 0;
stack->next = NULL;
//上面一段用于栈的初始化
printMap();
search(1,1);//从(1,1)位置开始搜索
system("pause");
}
int now = 0;//当已经找到出路时,将now置为1,以结束递归
//(否则,如果还有别的路径,就会输出另一条路径的一部分,此bug暂时还没修复)
int search(int x, int y)
{
if (now)return 0;
if (x > 10 || y > 10 || x < 0 || y < 0) return 0;
if (x == 8 && y == 8) {//找到出口,打印所有路径
now = 1;
push(8, 8);
int flag = 1;
while (flag)
flag = pop_print();
return 0;
}
push(x, y);//将坐标入栈
if (book[x][y] == 1) {
pop();
return 0;
}
book[x][y]=1;//将走过的点置为1,下次探索到这个点时直接return;
if (MAP[x][y + 1] != '#') //右边不是障碍物,则向右探索,下同
search(x, y + 1);//注意,这里不能用!!!y++!!!
//我之前就是用了y++导致找了好几天bug。
//如果用y++,那么一小段深搜结束返回时,y的值是被加 1 的了。
//等于不在是在原有坐标换个位置探索了!!!
if (MAP[x + 1][y] != '#')
search(x + 1, y);
if (MAP[x - 1][y] != '#')
search(x - 1, y);
if (MAP[x][y - 1] != '#')
search(x, y - 1);
pop();//如果以上情况都不是,也将其出栈
return 0;
}
int pop_print()//打印栈中元素
{
if (stack->next != NULL) {
printf("(%d,%d)\t", stack->next->row, stack->next->column);
stack->next = stack->next->next;
if (stack->next == NULL )return 0;//如果栈中的元素都打印了,返回0
else return 1;
}
putchar('\n');
return 0;
}
void pop()//出栈
{
if(stack->next != NULL )
stack->next = stack->next->next;
}
void push(int a ,int b)//传入的是坐标,将其记录到栈中
{
link NowNode = (link )malloc(sizeof(node));
if (!NowNode) exit(0);
NowNode->row = a;
NowNode->column = b;
NowNode->next = stack->next;
stack->next = NowNode;
}
void printMap()//打印地图
{
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++)
putchar(MAP[i][j]);
putchar('\n');
}
}