【深度優先_棧】:輸出迷宮的所有路徑,並求出最短路徑長度及最短路徑
阿新 • • 發佈:2019-01-03
//要求輸出迷宮的所有路徑,並求出最短路徑長度及最短路徑。 //入口座標設為(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; }