#include
#include
#include
#define M 8
#define N 8
#define MaxSize 100
//每个元素表示一个方块,为0对应的通道,为1对应的为墙
int mg[M + 2][N + 2] =
{ {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} };
typedef struct {
int i; //当前方块的行号
int j; //当前方块的列号
int di; //di是下一个可行走的相邻方块的方位号
}Box;
typedef struct {
Box data[MaxSize];
int top;
}StType;
int mgpath(int xi, int yi, int xe, int ye) {//求解的路径为(xi,yi)-->(xe,ye)
int i, j, k, di, find;
StType st;
st.top = -1;
st.top++;
st.data[st.top].i = xi;
st.data[st.top].j = yi;
st.data[st.top].di = -1;
mg[xi][yi] = -1;
while (st.top > -1) {
i = st.data[st.top].i;
j = st.data[st.top].j;
di = st.data[st.top].di;
if (i == xe && j == ye) {
printf("迷宫路径如下\n");
for (k = 0; k <= st.top; k++) {
printf("(%d,%d)", st.data[k].i, st.data[k].j);
if (k % 5 == 0) printf("\n");
}
return 1;//找到路径,返回真
}
find = 0;
while (di < 4 && find == 0) {//寻找下一个方块
di++;
switch (di) {
case 0:i = st.data[st.top].i + 1, j = st.data[st.top].j;
break;
case 1:i = st.data[st.top].i, j = st.data[st.top].j + 1;
break;
case 2:i = st.data[st.top].i - 1, j = st.data[st.top].j;
break;
case 3:i = st.data[st.top].i, j = st.data[st.top].j - 1;
break;
}
if (mg[i][j] == 0) find = 1;
}
if (find == 1) {
st.data[st.top].di = di;
st.top++;
st.data[st.top].i = i;
st.data[st.top].j = j;
mg[i][j] = -1; //避免重复走到该方块
}
else { //没录可走,则退栈
mg[st.data[st.top].i][st.data[st.top].j] = 0;
st.top--; //将该方块退栈
}
}
return 0;//没有路径可走,返回假
}
int main() {
if (!mgpath(1, 1, M, N)) {
printf("该问题无解!");
}
}
此解不一定是最优解,即不是最短路径!
下面的为最优解
#include
#include
#include
#define M 8
#define N 8
#define MaxSize 100
//每个元素表示一个方块,为0对应的通道,为1对应的为墙
int mg[M + 2][N + 2] =
{ {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} };
typedef struct {
int i, j;//方块位置
int pre;//本路径中上一块在队列中的下标
}Box;
typedef struct {
Box data[MaxSize];
int front, rear;
}QuType;
void print(QuType qu, int front) {
int k = front, j;
do {//反向找到最短的路径,将该路径上的方块的pre标记为-1
j = k;
k = qu.data[k].pre;
qu.data[j].pre = -1;
} while (k != -1);
for (k = 0; k < MaxSize; k++) {//正向搜索pre为-1的方块,即构成正向路径
if (qu.data[k].pre == -1)
printf("(%d,%d) ", qu.data[k].i, qu.data[k].j);
}
printf('\n');
}
int mgpath(int xi, int yi, int xe, int ye) {
int i, j, find = 0, di;
QuType qu;
qu.front = qu.rear = -1;
qu.rear++;
qu.data[qu.rear].i = xi;
qu.data[qu.rear].j = yi;
qu.data[qu.rear].pre = -1;
mg[xi][yi] = -1; //将其赋值为1,以避免回过来重复搜索
while (qu.front != qu.rear && !find) {//队列不为空且找到路径时循环
qu.front++; //出队,由于不是韩星队列,该队列元素任然在队列中
i = qu.data[qu.front].i;
j = qu.data[qu.front].j;
if (i == xe && j == ye) {//找到出口
find = 1;
print(qu, qu.front);
return 1;
}
for (di = 0; di < 4; di++) {//扫描各个方位,并把可走的方位放到队列中
switch (di) {
case 0:i = qu.data[qu.front].i + 1, j = qu.data[qu.front].j; break;
case 1:i = qu.data[qu.front].i, j = qu.data[qu.front].j + 1; break;
case 2:i = qu.data[qu.front].i - 1, j = qu.data[qu.front].j; break;
case 3:i = qu.data[qu.front].i, j = qu.data[qu.front].j - 1; break;
}
if (mg[i][j] == 0) {
qu.rear++;
qu.data[qu.rear].i = i;
qu.data[qu.rear].j = j;
qu.data[qu.rear].pre = qu.front;//保存路径上一个方块的下标
mg[i][j] = -1;//将其赋值为1,以避免回过来重复搜索
}
}
}
return 0;
}
int main() {
if (!mgpath(1, 1, M, N))
printf("该问题无解!");
}