//要求輸出迷宮的所有路徑,並求出最短路徑長度及最短路徑。
//入口座標設爲(1,1),出口座標設爲(4,4)
#include<stdio.h>
#define M 4 //行數
#define N 4 //列數
#define MaxSize 100 //棧最多元素個數
int mg[M+2][N+2]= //一個迷宮,其四周要加上均爲1的外框,0表示可走節點,1表示障礙物
{
{1,1,1,1,1,1},
{1,0,0,0,1,1},
{1,0,1,0,0,1},
{1,0,0,0,1,1},
{1,1,0,0,0,1},
{1,1,1,1,1,1}
};
struct migong
{
int i; //路徑橫座標
int j; //路徑縱座標
int di; //方向值初始爲-1,0,1,2,3分別表示四個要查找的方向
}Stack[MaxSize],Path[MaxSize]; //定義棧和存放最短路徑的數組
int top= -1; //棧頂指針,初始值爲-1
int count= 1; //路徑數計數
int minlen=MaxSize; //最短路徑長度
void mgpath() //路徑爲:(1,1)->(M,N)
{
int i,j,di,nextfound,k;
//初始結點進棧
top++;
Stack[top].i=1;
Stack[top].j=1;
Stack[top].di=-1; //該點的初始方向值-1,表示還沒查找過從此出發的其他4個方向
mg[1][1]=-1; //-1表示該節點位置進棧過(最好用其他數組來標示)
while(top> -1) //棧不空時循環
{
//1 -----獲取棧頂
i=Stack[top].i;
j=Stack[top].j;
di=Stack[top].di; //棧頂元素的查找方向
//2 -----如果找到了出口(M,N),則輸出查找路徑,並退棧,用新的棧頂方向值取代當前的查找方向
if(i==M && j==N)
{
printf("M: ",count++);
for(k=0;k<=top;k++) //輸出路徑
{
printf("(%d,%d) ",Stack[k],i,Stack[k].j);
if((k+1)%5==0) //輸出時每5個結點換一行
printf("\n\t");
}
printf("\n");
if(top+1<minlen) //比較輸出最短路徑
{
for(k=0;k<=top;k++)
{
Path[k]=Stack[k]; //保存最短路徑
}
minlen=top+1;
}
mg[Stack[top].i][Stack[top].j]=0; //0表示讓該位置變爲其他路徑的可走結點
//讓元素出棧
top--;
//i=Stack[top].i;
//j=Stack[top].j;
di=Stack[top].di; //記錄下一次的查找方向爲新棧頂的的查找方向
}
//3 -------在當前棧頂的基礎上找到下一個可走節點,如果當前棧頂的4個方向都走完了,則退棧找新的棧頂
nextfound=0;
while(di<4 && nextfound==0) //找下一個可走結點
{
di++; //下一個查找方向
switch(di) //計算下一個查找方向的座標
{
case 0: i=Stack[top].i-1; j=Stack[top].j; break; //上面
case 1: i=Stack[top].i; j=Stack[top].j+1; break; //右邊
case 2: i=Stack[top].i+1; j=Stack[top].j; break; //下面
case 3: i=Stack[top].i; j=Stack[top].j-1; break; //左邊
}
if(mg[i][j]==0) //如果下一個可走節點沒有進棧過,標記find爲1表示找到了下一個可走節點
{
nextfound=1;
}
}
if(nextfound == 1) //從當前棧頂上找到了下一個可走結點
{
Stack[top].di=di; //更新棧頂元素的di值爲最新的查找方向
//下一個可走結點進棧
top++;
Stack[top].i=i;
Stack[top].j=j;
Stack[top].di=-1;
mg[i][j]=-1;
}
else //如果當前棧頂的4個方向都已經查找完
{
mg[Stack[top].i][Stack[top].j]=0; //0表示讓該位置變爲其他路徑的可走結點
top--; //當前棧頂已經查找完,讓它出棧
}
}
printf("最短路徑如下:\n");
printf("長度: %d\n",minlen);
printf("路徑: ");
for(k=0;k<minlen;k++)
{
printf("(%d,%d) ",Path[k].i,Path[k].j);
if((k+1)%5==0) //輸出時每5個結點換一行
printf("\n\t");
}
printf("\n");
}
int main()
{
printf("迷宮所有路徑如下:\n");
mgpath();
return 0;
}
【深度優先_棧】:輸出迷宮的所有路徑,並求出最短路徑長度及最短路徑
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.