順序佇列求解迷宮(最優解)
阿新 • • 發佈:2019-01-05
【問題描述】
以一個mXn的長方陣表示迷宮,0和1分別表示迷宮中的通路和障礙。設計一個程式,對任意設定的迷宮,求出一條從入口到出口的通路,或得出沒有通路的結論。
【任務要求】
實現佇列求解迷宮從入口到出口的最短通路。
【測試資料】
迷宮的測試資料如下:左上角(0,1)為入口,右下角(8,9)為出口。
程式碼:
這裡寫程式碼片
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct
{
int x;//記錄橫座標
int y;//記錄縱座標
int place;//用來記錄上(結點)的位子
}NODE;//佇列(結點)的資料型別
typedef struct
{
NODE data[MAX];//佇列
int head;//對頭
int end;//對尾
}DATA;
DATA *Create()//初始化隊
{
DATA *p;
p = (DATA *)malloc(sizeof(DATA));//給p指標分個空間
if (p == NULL)
{
printf("error");
}
else
{
p->head = -1;//初始化頭指標為-1
p->end = -1 ;//初始化尾指標為-1
}
return p;
}
int Verdictqueue(DATA *p)//判斷隊是否為空
{
if (p->end == MAX)
return 0;
else
return 1;
}
void Iputqueue(DATA *p, NODE s)//進棧函式
{
if (Verdictqueue(p))
{
p->data[++(p->end)] = s;//將元素s入棧(尾指標先加,因為首次是從-1開始的)
}
}
int main()
{
DATA *p;
NODE H, E, S;//H,E記錄頭尾座標的變數的,S臨時記錄的變數
int i, j, x;//全是迴圈或者 臨時記錄的變數
int M[10][10] = {
{ 1,0,1,1,1,1,1,1,1,1 },//1
{ 1,0,0,1,0,0,0,1,0,1 },//2
{ 1,0,0,1,0,0,0,1,0,1 },//3
{ 1,0,0,0,0,1,1,0,0,1 },//4
{ 1,0,0,1,1,0,0,0,0,1 },//5
{ 1,0,0,0,1,0,0,0,0,1 },//6
{ 1,0,1,0,0,0,1,1,0,1 },//7
{ 1,0,1,1,1,0,1,1,0,1 },//8
{ 1,1,0,0,0,0,0,0,0,0 },//9
{ 1,1,1,1,1,1,1,1,1,1 }//10
};
p = Create();//呼叫函式 初始化隊
H.x = 0; H.y = 1; H.place = 0;//起始座標 和起始位置(H.place=0)打包在變數H中
E.x = 8; E.y = 9;//同理尾位置打包在E變數
Iputqueue(p, H);//將起始位置入隊
M[H.x][H.y] = 2;//標記走過
while (p->head != p->end)//頭指標沒追上尾指標 表示有路,追上了退出 無路
{
p->head++;//每次頭指標後移一位
for (i = 1; i <= 4; i++)//四個方向的迴圈
{/*將頭指標裡的資料拿出來作為 參考點 遍歷其周圍四個方向*/
S.x = p->data[p->head].x;
S.y = p->data[p->head].y;
S.place = p->head;//將參考點座標 記下 它周圍有滿足條件的座標時 一起入隊(方便找到出口時可以根據線索返回)
switch (i)
{
case 1: {//上方向
if (M[S.x - 1][S.y] == 0)
{
S.x = S.x - 1; S.y = S.y;
Iputqueue(p, S);
M[S.x][S.y] = 2;
}
}; break;
case 2: {//右方向
if (M[S.x][S.y + 1] == 0)
{
S.x = S.x; S.y = S.y + 1;
Iputqueue(p, S);
M[S.x][S.y] = 2;
}
}; break;
case 3: {//下方向
if (M[S.x + 1][S.y] == 0)
{
S.x = S.x + 1; S.y = S.y;
Iputqueue(p, S);
M[S.x][S.y] = 2;
}
}; break;
case 4: {//左方向
if (M[S.x][S.y - 1] == 0)
{
S.x = S.x - 1; S.y = S.y;
Iputqueue(p, S);
M[S.x][S.y] = 2;
}
}; break;
}
}
if (p->data[p->head].x == E.x&&p->data[p->head].y == E.y)//找到出口 退出迴圈
break;
}
/*for (j = 0; j<10; j++)
{
for (i = 0; i<10; i++)
printf("%d,", M[j][i]);
printf("\n");
}*///列印迷宮
x = p->head;//結束時的座標的下標
while (x>0)
{
printf("(%d,%d)\n", p->data[x].x, p->data[x].y);
x = p->data[x].place;//上一個(結點)的下標是本(結點)的place存的值
}
return 0;
}