实验名称
利用栈和队列的迷宫求解
一、实验内容
利用所学知识,用栈和队列实现迷宫求解,找出一条迷宫路径
二、实现
#include <iostream>
#include <windows.h>
using namespace std;
typedef struct PosType
{
int x;
int y;
} PosType;
typedef struct Elem //栈元素的属性
{
int ord; //路径上的顺序
int di; // 上下左右的序号
PosType seat; //位置
} Elem; //每一个格子的类型
typedef struct StackType
{
int base; //栈底指针
int top; //栈顶指针
int stacksize;
Elem data[1000];
} Stack, *SqStack;
typedef struct Queuenode //队列元素的属性
{
PosType pre; //记录前一个节点
PosType seat; //自身位置
} qElem;
typedef struct QueueType
{
int front; //队首指针
int rear; //队尾指针
int queuesize;
qElem data[1000];
} Queue, *Queueptr;
SqStack InitStack() //初始化一个栈
{
Stack S = {0, 0, 1000, {0}};
SqStack Sptr = &S;
return Sptr;
}
void Push(SqStack S, Elem e)
{
if (S->top - S->base >= S->stacksize) //满了
{
cout << "The stack is full" << endl;
}
S->data[S->top] = e;
S->top++;
}
void Pop(SqStack S, Elem &e)
{
if (S->top != S->base) //栈不空
{
S->top--;
e = S->data[S->top];
}
else
{
cout << "The stack is empty" << endl;
}
}
bool StackEmpty(SqStack S)
{
if (S->top == S->base)
return true;
else
return false;
}
Queueptr InitQueue()
{
Queue Q = {0, 0, 1000, {0}};
Queueptr Qptr = &Q;
return Qptr;
}
void EnQueue(Queueptr Q, qElem e) //入队
{
if ((Q->rear + 1) % Q->queuesize != Q->front)
{
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % Q->queuesize;
}
else
cout << "The stack is full" << endl;
}
void DeQueue(Queueptr Q, qElem &e)
{
if (Q->rear != Q->front) //不为空
{
e = Q->data[Q->front];
Q->front = (Q->front + 1) % Q->queuesize;
}
else
cout << "The stack is empty" << endl;
}
bool QueueEmpty(Queueptr Q)
{
if (Q->rear == Q->front)
return true;
else
return false;
}
bool MazePath_Stack(int maze[][10], PosType start, PosType end)
{
SqStack S = InitStack();
PosType curpos = start; //当前位置
int curstep = 1;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0}; //四个方向
do
{
if (maze[curpos.x][curpos.y] == 0) //未走过
{
Elem temp = {curstep, 1, curpos}; //定义一个栈元素类型的临时变量,用于压栈
Push(S, temp); //加入路径
maze[curpos.x][curpos.y] = curstep; //在迷宫中标记路径
curstep++;
if (curpos.x == end.x && curpos.y == end.y)
return true;
curpos.y += 1; //东邻
}
else
{
if (!StackEmpty(S))
{
Elem e = {0, 0, {0, 0}};
Pop(S, e);
curstep--; //路径序号减一
while (e.di == 4 && !StackEmpty(S)) //该点四个方向都走过了
{
maze[e.seat.x][e.seat.y] = -1; //标记一下,此点不可走了
Pop(S, e);
curstep--;
}
if (e.di < 4)
{
e.di++;
Push(S, e); //选择下一个方向相邻的点之后,这个节点再入栈
curstep++;
curpos = e.seat;
curpos.x += dx[e.di - 1];
curpos.y += dy[e.di - 1]; //找邻接点
}
}
}
} while (!StackEmpty(S));
return false;
}
void PrintPath_Stack(int maze[][10], PosType start)
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (maze[i][j] == 1)
{
if (i == start.x && j == start.y)
cout << 1 << ' ';
else
cout << '#' << ' ';
}
else if (maze[i][j] == -1)
{
cout << '$' << ' ';
}
else if (maze[i][j] == 0)
{
cout << " ";
}
else
{
if (maze[i][j] >= 10)
cout << maze[i][j];
else
cout << maze[i][j] << ' ';
}
}
cout << endl;
}
}
bool Mazepath_Queue(int maze[][10], qElem save[][11], PosType start, PosType end) // save是保存每个节点的信息的数组
{
Queueptr Q = InitQueue();
qElem firstnode = {{-1, -1}, start}; //第一个节点是start,其pre是(-1,-1)
EnQueue(Q, firstnode);
maze[start.x][start.y] = 2; // 2表示走过了
save[start.x][start.y] = firstnode;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0}; //四个方向
while (!QueueEmpty(Q))
{
qElem e = {{0, 0}, {0, 0}};
DeQueue(Q, e); //队首出队
for (int i = 0; i < 4; i++) //查看周围元素
{
int x = e.seat.x + dx[i];
int y = e.seat.y + dy[i];
if (maze[x][y] != 1 && maze[x][y] != 2) //不是障碍并且没走过
{
qElem curnode = {{e.seat.x, e.seat.y}, {x, y}}; //当前节点
EnQueue(Q, curnode);
maze[x][y] = 2;
save[x][y] = curnode;
if (x == end.x && y == end.y) //找到终点
return true;
}
}
}
return false;
}
void PrintPath_Queue(int maze[][10], qElem save[][11], PosType end)
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (maze[i][j] == 2)
maze[i][j] = 0; //取消走过的标记
}
}
int a = end.x;
int b = end.y; //当前坐标
while (1)
{
maze[a][b] = 3;
int m = a, n = b;
a = save[m][n].pre.x;
b = save[m][n].pre.y;
if (a == -1 && b == -1)
break;
}
int cnt = 1;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (maze[i][j] == 3)
{
cout << cnt;
if (cnt < 10)
cout << ' ';
cnt++;
}
else if (maze[i][j] == 1)
cout << "# ";
else
cout << " ";
}
cout << endl;
}
}
int main()
{
/*int maze[10][10] = {
{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}};*/
int maze[10][10] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 0, 0, 1, 0, 1},
{1, 1, 0, 1, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
PosType start = {1, 1};
PosType end = {8, 8};
qElem save[11][11] = {};
if (Mazepath_Queue(maze, save, start, end))
PrintPath_Queue(maze, save, end);
/*if(MazePath_Stack(maze, start, end))
PrintPath_Stack(maze, start);*/
else
cout << "There is no path in the maze" << endl;
system("pause");
}