求由(1,1)到終點的最短步數,並輸出對應的路徑。
1.利用層序遍歷,不斷擴展延伸。
2.用隊列存儲。存儲父親節點,找其所有的兒子節點。然後父節點出隊,兒子節點變爲新父節點,然後找新父節點的所有兒子節點,以此類推。
3.用數組實現隊列。
/*
層序遍歷實現廣度優先搜索。
*/
#include"stdio.h"
#include"string.h"
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//右,下,左,上。
int a[50][50];
int book[50][50];
struct Node
{
int x;
int y;
int step;//步數
int parents;
};
struct Node queue[2501];
int main()
{
int head=1;//指向父節點
int rear=1;//rear指向最後一個元素的下一位置
int start_x,start_y;//起點座標設置爲(1,1)
int flag=0;//flag=0沒有找到,flag=1找到出口。
int n,m;//地圖的行和列
int p,q; //地圖出口
int i,j;
int next_x,next_y;
scanf("%d %d",&n,&m );//scanf("%d,%d",&n,&m )控制檯輸入方式 1,2 scanf("%d %d",&n,&m )控制檯輸入方式 1 2
for(i=0;i<50;i++)//清空數組
{
for(j=0;j<50;j++)
{
book[i][j]=0;
a[i][j]= 0;
}
}
for(i=1;i<=n;i++)//地圖輸入,從1開始符合習慣。
{
for(j=1;j<=m ;j++)
{
scanf("%d",&a[i][j]);
}
}
scanf("%d %d %d %d",&start_x,&start_y,&p,&q);
queue[head].x=start_x;//起點座標入隊
queue[head].y=start_y;
queue[head].step=0;
book[start_x][start_y]=1;//這行別忘了講起點做入隊標記 ,否則會重複到起點1,1。無限次遍歷。
rear++; //不要忘記這句,否則會把起點覆蓋。而且head==tial,進不去循環。
while(head <rear) //全部出隊時,隊列空,代表嘗試了所有可能的情況
{
for(i=0;i<=3;i++)
{
next_x=queue[head].x+next[i][0];
next_y=queue[head].y+next[i][1];
if(next_x <1||next_x>n||next_y <1||next_y>m)//越界判斷不要忘記否則會跳不出循環
continue;//越界元素不入隊
if(a[next_x][next_y]==0&&book[next_x][next_y]==0)//入隊條件判斷:不是障礙物,未曾入隊。
{ book[next_x][next_y]=1;//標記座標(next_x,nexty)入隊
queue[rear].x=next_x;//入隊
queue[rear].y=next_y;
queue[rear].step=queue[head].step+1;//子節點(此層)爲父節點(是上層)步數加一
queue[rear].parents =head;//保存其父節點位置。
rear++;//rear++和 queue[rear].step=queue[head].step+1的次序不能變,否則就會出錯。
}
if(next_x==p&&next_y==q)//與遞歸不同,層序遍歷,最先找到出口的座標,停止往下層拓展時,步數就是最短的。
{
flag=1;
break;
}
}
if(flag==1)
{
break;
}
head++;//四個方向全部嘗試完畢,父節點出隊
}
printf("找到出口的步數是%d\n",queue[rear-1].step);//rear-1是最後一個入隊的元素的位置。
int position;//保存父節點位置
position=rear-1;
printf("走出迷宮的最短軌跡是:(%d %d)<----",queue[position].x,queue[position].y);
while(queue[position].x!=start_x&&queue[position].y!=start_y)
{
position=queue[position].parents;//滑動更新父節點位置 ,滑動窗口思想
printf("(%d %d)<----",queue[position].x,queue[position].y);
}
printf("(%d %d)",start_x,start_y);
}