1.用栈解决迷宫问题,比较暴力,实际上是经过大量的试错才得出的路径
问题分析
a.首先画出图,我用1代表墙,用0代表非墙。
b.首先要规定入口的坐标位置
c.然后规定寻找的方向规则比如 先每到一个位置先看下该点的左侧是否非墙,如果是返回该点的坐标并将该点对应的下标(在之后要用该下标解析出对应的坐标
)入栈,如果是墙的话,就看该点的下面是否非墙…总之我规定的顺序是左-下-右-上
。(这个也是该代码的灵魂所在)。
d.上面当你遇到死胡同时该怎么办,那么就要考虑出栈
了(这时就要将下标套现成坐标
)然后再进行上述的方向判断,但是你想想是不是还欠点什么,当你第一次判断该点的下方可行的时候将该点进栈,当你出去的时候在进行判断,是不是还要进入该点的下方,那么此时就会陷入死循环,别急,那么我们就需要设置一个判断是否来过该点的标志visited[2]={0,1}
,0
代表没来过,1
代表来过,所以在最开始的时候要遍历图将图全部初始化为未来过。
#include
#include
#include
#define MAXSIZE 100
typedef struct
{
int stack[MAXSIZE];//顺序栈
int top;
}STACK,*SeqStack;
void initStack(SeqStack S)//初始化要将地址传进去
{
memset(S->stack, 0, sizeof(S->stack));//初始化函数
S->top = -1;
}
void Push(SeqStack S, int way)//入栈
{
if (S->top == MAXSIZE - 1)
{
printf("栈已满\n");
}
else
{
(S->top)++;
S->stack[S->top] = way;//栈存的元素是按照1-100的顺序存的
}
}
void Pop(SeqStack S)//出栈让其返回坐标
{
if (S->top == -1)
{
printf("栈已空\n");
}
else
{
S->stack[--S->top];
}
}
int* IsPass(SeqStack S, char map[][10],int visited[][10],int *arr)
{
if (map[arr[0]][arr[1]-1] != 1)//左
{
if (visited[arr[0]][arr[1]-1] != 1)
{
Push(S, 10 * arr[0] + arr[1]-1);//入栈之后将该位置赋值为1代表访问过该点
visited[arr[0]][arr[1]-1] = 1;//判断该点来过
arr[1] = arr[1] - 1; //更新坐标
map[arr[0]][arr[1]] = 1;//将该点的内容变为墙。//该处有些小问题,你可以在最后打印图的时候用是否访问过来打印图。我只是为了找到路径,所以改变非墙的信息是可以的。
}//将标号入栈
}
else if (map[arr[0] + 1][arr[1]] != 1)//下
{
if (visited[arr[0] + 1][arr[1]] != 1)
{
Push(S, 10 * (arr[0] + 1) + arr[1]);
visited[arr[0] + 1][arr[1]] = 1;
arr[0] = arr[0] + 1;
map[arr[0]][arr[1]] = 1;
}
}
else if (map[arr[0]][arr[1] + 1] != 1)//右
{
if (visited[arr[0]][arr[1] + 1] != 1)
{
Push(S, 10 * arr[0] + arr[1] + 1);
visited[arr[0]][arr[1] + 1] = 1;
arr[1] = arr[1] + 1;
map[arr[0]][arr[1]] = 1;
}
}
else if (map[arr[0] - 1][arr[1]] != 1)//上
{
if (visited[arr[0] - 1][arr[1]] != 1)
{
Push(S, 10 * (arr[0] - 1) + arr[1]);
visited[arr[0] - 1][arr[1]] = 1;
arr[0] = arr[0] - 1;
map[arr[0]][arr[1]] = 1;
}
}
else//遇到死胡同该怎么办将ij点的信息出栈
{
Pop(S);//出栈后但是i,j没发生变化
int a = S->stack[S->top];
arr[0] = a / 10;
arr[1] = a % 10;
}
return arr;
}//方向判断
void print(SeqStack S)
{
int a, b;
for (int i = 0; i < S->top; i++)
{
a = S->stack[i] / 10;
b = S->stack[i] % 10;
printf("(%d,%d)\t", a, b);
}
}
void Graph(char map[][10])
{
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
if (map[i][j] == 1)
{
printf("■");
}
else
{
if ((i == 1 && j == 1) || (j == 8 && i == 8))
{
printf("OO");//因为上述的`■`占两个字节
}
else
{
printf(" ");//两个空格
}
}
}
printf("\n");
}
}
int main()
{
char map[10][10] = {//1表示墙,0表示可走的路//地图
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 0, 1, 1, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 0, 0, 0, 1, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};
Graph(map);
int visited[10][10] = { 0 };
SeqStack S;
S = (SeqStack)malloc(sizeof(STACK));//定义对象
initStack(S);//初始化
int i = 1, j = 1;
visited[i][j] = 1;
int arr[2] = { i,j };
do
{
IsPass(S, map,visited, arr);//
} while (!(arr[0]==8&&arr[1]==8));
/*printf("找到的路径图如下:\n");
for (i = 0; i < S->top; i++)
{
printf("%d\t", S->stack[i]);
}*/
printf("找到的路径图如下:\n");
print(S);
system("pause");
return 0;
}