而且在求解迷宮路徑中,所求得的路徑必須是簡單路徑。即在求得的路徑上不能有重複的同一塊通道。
爲了表示迷宮,設置一個數組,其中每個元素表示一個方塊的狀態,爲0時表示對應方塊是通道,爲1時表示對應方塊爲牆,數組如下所示:
int mg[10][10] = { //定義一個迷宮,0表示通道,1表示牆
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,1,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}};
對於迷宮中每個方塊,都有上下左右四個方塊相鄰,第i行第j列的當前方塊的位置爲(i,j),規定上方方塊爲方位0,按順時針方向遞增編號。假設從方位0到方位3的方向查找下一個可走方塊。
爲便於回溯,對於可走的方塊都要進棧,並試探它的下一個可走方位,將這個可走的方位保存到棧中,棧定義如下:
struct St //定義一個棧,保存路徑
{
int i; //當前方塊的行號
int j; //當前廣場的列號
int di; //di是下一可走方位的方位號
} St[MaxSize]; //定義棧
求解路徑過程爲:先將入口進棧(初始方位設置爲-1),在棧不爲空時循環:取棧頂方塊(不退棧),若是出口,則輸出棧中方塊即爲路徑。否則,找下一個可走的相鄰方塊,若不存在這樣的方塊,則退棧。若存在,即將其方位保存到棧頂元素中,並將這個可走相鄰方塊進棧(初始方位設置爲-1)。
爲保證試探可走相鄰方塊不是已走路徑上的方塊,如(i,j)已經進棧,在試探(i+1,j)的下一可走方塊時,又試探到(i,j),這樣會引起死循環,爲此,在一個方塊進棧後,將對應的mg數組元素值改爲-1(變爲不可走),當退棧時(沒有可走的相鄰方塊),將其恢復爲0.
算法如下:
#include <iostream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
#define MaxSize 100
int mg[10][10] = { //定義一個迷宮,0表示通道,1表示牆
{1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,1,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}};
struct St //定義一個棧,保存路徑
{
int i; //當前方塊的行號
int j; //當前廣場的列號
int di; //di是下一可走方位的方位號
} St[MaxSize]; //定義棧
int top = -1; //初始化棧指針
void MgPath(int xi, int yi, int xe, int ye) //路徑爲從(xi,yi)到(xe,ye)
{
int i, j, di, find, k;
top++; //初始方塊進棧
St[top].i = xi;St[top].j = yi;St[top].di = -1;
mg[xi][yi] = -1;
while(top>-1) //棧不爲空時循環
{
i = St[top].i;j = St[top].j;di = St[top].di;
if(i==xe && j==ye) //找到了出口,輸出路徑
{
cout << "迷宮路徑如下:/n";
for(k=0; k<=top; k++)
{
cout << "/t(" << St[k].i << "," << St[k].j << ")";
if((k+1)%5==0) cout << endl; //每輸出五個方塊後換一行
}
cout << endl;
return;
}
find = 0;
while(di<4 && find==0) //找下一個可走方塊
{
di++;
switch(di)
{
case 0:i = St[top].i-1; j = St[top].j; break;
case 1:i = St[top].i; j = St[top].j+1; break;
case 2:i = St[top].i+1; j = St[top].j; break;
case 3:i = St[top].i; j = St[top].j-1; break;
}
if(mg[i][j]==0) find = 1; //找到通路
}
if(find==1) //找到了下一個可走方塊
{
St[top].di = di; //修改原棧頂元素的di值
top++; //下一個可走方塊進棧
St[top].i = i; St[top].j = j; St[top].di = -1;
mg[i][j] = -1; //避免重複走到這個方塊
}
else //沒有路可走,則退棧
{
mg[St[top].i][St[top].j] = 0; //讓該位置變成其它路徑可走方塊
top--;
}
}
cout << "沒有可走路徑!/n";
}
int main()
{
MgPath(1,1,8,8);
}