c 解迷宫示例代码:
#include <stdio.h>
#include <stdlib.h>
#define row 15
#define column 21
#define Max 500
typedef struct{
int x,y; /*搜索位置的坐标 */
int pre; /*表示前驱点的位置索引 */
}Footprint;
typedef struct{
int i,j; /*4个搜索方向的坐标变化值 */
}Direction;
int maze[row+2][column+2]= /* 定义四周为墙。故为row+2,column+2, 0 为通路,1为墙 */
{
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1},
{1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};
Footprint foots[Max];
// 左右上下,注意,此处列值移动为左右,行值移动为上下,直接与MAZE 数组下标运算
Direction Direct[4]={{0,-1},{0,1},{-1,0},{1,0}};
void print_result(int tail)
{
int i,j,k;
k=tail;
do
{
i=foots[k].x; j=foots[k].y;
maze[i][j]=3;
k=foots[k].pre; // 由后继找到它的前趋。
}while(k);
/*
for(i=1;i<=k;i++)
{
maze[foots[i].x][foots[i].y]=3;
}
*/
printf("模拟迷宫路径: @ 表示最后走出迷宫的路径, -1表示探索过的路径/n");
printf("进入->/n");
for (i=1;i<=row;i++)
{
for (j=1;j<=column;j++)
{
if (maze[i][j]==3) printf("%2c",'@');
else printf("%2d",maze[i][j]);
}
if (i==row) printf("->走出/n/n");
else printf("/n");
}
}
void main(void)
{
int i,j,k,newi,newj,QueueHead,QueueTail;
int Gotit=0;
QueueHead=0;QueueTail=1; //ensure foots[0] is 0
foots[QueueTail].x=1;foots[QueueTail].y=1;foots[QueueTail].pre=0; maze[1][1]=-1; //入口入队列(1,1)
do {
QueueHead++; i=foots[QueueHead].x; j=foots[QueueHead].y; /*下一步出队列 */
if(i==15&& j==18)
{
printf("%d,%d/n",i,j);
}
for (k=0;k<4;k++){ /*沿4个方向搜索*/
newi=i+Direct[k].i; newj=j+Direct[k].j; /*确定新的搜索位置 */
if (!maze[newi][newj]) { /*如果新位置是未搜索通道,则将新位置入队列*/
QueueTail++; foots[QueueTail].x=newi;foots[QueueTail].y=newj;
foots[QueueTail].pre=QueueHead; // 标识新结点的前趋
maze[newi][newj]=-1; /*标识搜索过的位置为-1 来了就算搜索过*/
}
if (newi==row && newj==column){ /*找到出口*/
print_result(QueueTail); Gotit=1;
break; // pay attention
}
}
}while(QueueHead<QueueTail); // 未搜索完,继续
if (!Gotit) printf("No Pass!/n");
system("pause");
}
注意:如果找到了出口,继续搜索却找不到所有路径
因为搜索互相堵路了。 是不是只能有深度搜索才能找到全路径呢?
-------------------------------------------------------------------------------------------------------
c++ 的示例代码:
#include<iostream.h>
#define up 1
#define down 2
#define left 3
#define right 4
#define wrong 0
int in_a,in_b;//定义入口
int out_a,out_b;//定义出口
int direction;//定义一个方向向量
int Width=0;
int Height=0;
/*
direction=2-->从上向下进行宽度遍历
direction=1-->从下向上进行宽度遍历
direction=4-->从左向右进行宽度遍历
direction=3-->从右向左进行宽度遍历
*/
/**********成员函数声明**********/
void printf(int **x,int Hei,int Wid);//输出二维数组
int GetDirection(int a,int b);//得到一个宽度遍历迷宫图的方向
void visit(int a,int b,int **m,int **v);//访问单个结点,a,b,表示结点坐标
void search(int direction,int **m,int **v);//宽度遍历整个迷宫
void back_check(int **m,int **v,int in_a,int in_b);//处理意外情况
void outputpath(int **v,int in_a,int in_b);//输出最短路径
void main()
{
cout<<"请输入迷宫尺寸大小:"<<endl;
cout<<"宽:";
cin>>Width;
cout<<"高:";
cin>>Height;
int key=1;
while(key==1){
int **value=new int*[Height];//动态创建迷宫路径矩阵
for(int y=0;y<Height;y++)
value[y]=new int[Width];
for(int k=0;k<Height;k++){//初始化迷宫路径矩阵
for(int t=0;t<Width;t++)
value[k][t]=0;
}
int **maze=new int*[Height];
for(int i=0;i<Height;i++)//动态创建迷宫矩阵
maze[i]=new int[Width];
cout<<"请输入迷宫矩阵,0代表路径,1代表障碍!"<<endl;
for(int count=0;count<Height;count++){
for(int j=0;j<Width;j++)
cin>>maze[count][j];
}
int a,b;
cout<<"请输入入口地址:";
cin>>a>>b;//初始化入口
in_a=a-1;
in_b=b-1;
cout<<"请输入出口地址:";
cin>>a>>b;//初始化出口
out_a=a-1;
out_b=b-1;
direction=GetDirection(out_a,out_b);//根据出口得到方向向量
value[out_a][out_b]=1;//从出口开始遍历,初始化为1
search(direction,maze,value);
back_check(maze,value,in_a,in_b);
cout<<"该迷宫用0,1矩阵表示为:"<<endl;
printf(maze,Height,Width);
cout<<"迷宫入口为:"<<'('<<in_a+1<<','<<in_b+1<<')'<<endl;
cout<<"迷宫出口为:"<<'('<<out_a+1<<','<<out_b+1<<')'<<endl;
cout<<"路径矩阵表示为:"<<endl;
printf(value,Height,Width);
outputpath(value,in_a,in_b);
cout<<"输入数字1继续,输入-1退出程序!"<<endl;
cin>>key;
}
}
void printf(int **x,int Hei,int Wid)
{
int i=0;//记录行数
while(i<Hei){
for(int j=0;j<Wid;j++)
cout<<x[i][j]<<',';
cout<<endl;
i++;
}
}
int GetDirection(int a,int b)
{
if(a==0) return down;
if(a==Height-1) return up;
if(b==0) return right;
if(b==Width-1) return left;
return wrong
}
void visit(int a,int b,int **m,int **v)
{
if(v[a][b]==0 || m[a][b]==1)
return;//不访问无值结点和障碍物结点
/********修改当前结点上方结点********/
if(a-1>=0 && m[a-1][b]==0){//保证上方有结点且不是障碍物
if(v[a-1][b]==0 || v[a][b]+1<v[a-1][b])
v[a-1][b]=v[a][b]+1;
}
/********修改当前结点下方结点********/
if(a+1<Height && m[a+1][b]==0){//保证下方有结点且不是障碍物
if(v[a+1][b]==0 || v[a][b]+1<v[a+1][b])
v[a+1][b]=v[a][b]+1;
}
/********修改当前结点左方结点********/
if(b-1>=0 && m[a][b-1]==0){//保证左方有结点且不是障碍物
if(v[a][b-1]==0 || v[a][b]+1<v[a][b-1])
v[a][b-1]=v[a][b]+1;
}
/********修改当前结点右方结点********/
if(b+1<Width && m[a][b+1]==0){//保证右方有结点且不是障碍物
if(v[a][b+1]==0 || v[a][b]+1<v[a][b+1])
v[a][b+1]=v[a][b]+1;
}
}
void search(int direction,int **m,int **v)
{
int count;//上下遍历时记录行数,左右遍历时记录列数
/**********向下遍历整个图**********/
if(direction==down){
count=0;//记录行标
while(count<Height){
for(int i=0;i<Width;i++){//找到该行中第一个被访问过的点
if(v[count][i]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向左遍历
visit(count,j,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(count,k,m,v);
count++;//进入下一行
}
}
/**********向上遍历整个图**********/
if(direction==up){
count=Height-1;//记录行标
while(count>=0){
for(int i=0;i<Width;i++){//找到该行中第一个被访问过的点
if(v[count][i]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向左遍历
visit(count,j,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(count,k,m,v);
count--;//进入上一行
}
}
/**********向右遍历整个图**********/
if(direction==right){
count=0;//记录列标
while(count<Width){
for(int i=0;i<Height;i++){//找到该列中第一个被访问过的点
if(v[i][count]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向上遍历
visit(j,count,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(k,count,m,v);
count++;//进入右一列
}
}
/**********向左遍历整个图**********/
if(direction==left){
count=Width-1;//记录列标
while(count>=0){
for(int i=0;i<Height;i++){//找到该列中第一个被访问过的点
if(v[i][count]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向上遍历
visit(j,count,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(k,count,m,v);
count--;//进入左一列
}
}
}
void back_check(int **m,int **v,int in_a,int in_b)//确保能够遍历到出口点
{
int direction;
if(v[in_a][in_b]==0){
direction=up;
search(direction,m,v);
direction=down;
search(direction,m,v);
direction=left;
search(direction,m,v);
direction=right;
search(direction,m,v);
}
}
void outputpath(int **v,int in_a,int in_b)
{
int a=in_a;
int b=in_b;
if(v[a][b]==0)
cout<<"没有通往出口的最短路径!!!"<<endl;
else{
cout<<"走出该迷宫的最短路径为:"<<endl;
while(v[a][b]!=1){
cout<<'('<<a+1<<','<<b+1<<')'<<"-->";
if(a-1>=0 && v[a-1][b]==v[a][b]-1){//上移
a=a-1;
continue;
}
if(a+1<Height && v[a+1][b]==v[a][b]-1){//下移
a=a+1;
continue;
}
if(b-1>=0 && v[a][b-1]==v[a][b]-1){//左移
b=b-1;
continue;
}
if(b+1<Width && v[a][b+1]==v[a][b]-1){//右移
b=b+1;
continue;
}
}
cout<<'('<<a+1<<','<<b+1<<')'<<endl;
}
}
----------------------------------------------------------------------------------------------
迷宫游戏:
#include<iostream.h>
#define up 1
#define down 2
#define left 3
#define right 4
#define wrong 0
int in_a,in_b;//定义入口
int out_a,out_b;//定义出口
int direction;//定义一个方向向量
int Width=0;
int Height=0;
/*
direction=2-->从上向下进行宽度遍历
direction=1-->从下向上进行宽度遍历
direction=4-->从左向右进行宽度遍历
direction=3-->从右向左进行宽度遍历
*/
/**********成员函数声明**********/
void printf(int **x,int Hei,int Wid);//输出二维数组
int GetDirection(int a,int b);//得到一个宽度遍历迷宫图的方向
void visit(int a,int b,int **m,int **v);//访问单个结点,a,b,表示结点坐标
void search(int direction,int **m,int **v);//宽度遍历整个迷宫
void back_check(int **m,int **v,int in_a,int in_b);//处理意外情况
void outputpath(int **v,int in_a,int in_b);//输出最短路径
void main()
{
cout<<"请输入迷宫尺寸大小:"<<endl;
cout<<"宽:";
cin>>Width;
cout<<"高:";
cin>>Height;
int key=1;
while(key==1){
int **value=new int*[Height];//动态创建迷宫路径矩阵
for(int y=0;y<Height;y++)
value[y]=new int[Width];
for(int k=0;k<Height;k++){//初始化迷宫路径矩阵
for(int t=0;t<Width;t++)
value[k][t]=0;
}
int **maze=new int*[Height];
for(int i=0;i<Height;i++)//动态创建迷宫矩阵
maze[i]=new int[Width];
cout<<"请输入迷宫矩阵,0代表路径,1代表障碍!"<<endl;
for(int count=0;count<Height;count++){
for(int j=0;j<Width;j++)
cin>>maze[count][j];
}
int a,b;
cout<<"请输入入口地址:";
cin>>a>>b;//初始化入口
in_a=a-1;
in_b=b-1;
cout<<"请输入出口地址:";
cin>>a>>b;//初始化出口
out_a=a-1;
out_b=b-1;
direction=GetDirection(out_a,out_b);//根据出口得到方向向量
value[out_a][out_b]=1;//从出口开始遍历,初始化为1
search(direction,maze,value);
back_check(maze,value,in_a,in_b);
cout<<"该迷宫用0,1矩阵表示为:"<<endl;
printf(maze,Height,Width);
cout<<"迷宫入口为:"<<'('<<in_a+1<<','<<in_b+1<<')'<<endl;
cout<<"迷宫出口为:"<<'('<<out_a+1<<','<<out_b+1<<')'<<endl;
cout<<"路径矩阵表示为:"<<endl;
printf(value,Height,Width);
outputpath(value,in_a,in_b);
cout<<"输入数字1继续,输入-1退出程序!"<<endl;
cin>>key;
}
}
void printf(int **x,int Hei,int Wid)
{
int i=0;//记录行数
while(i<Hei){
for(int j=0;j<Wid;j++)
cout<<x[i][j]<<',';
cout<<endl;
i++;
}
}
int GetDirection(int a,int b)
{
if(a==0) return down;
if(a==Height-1) return up;
if(b==0) return right;
if(b==Width-1) return left;
return wrong;
}
void visit(int a,int b,int **m,int **v)
{
if(v[a][b]==0 || m[a][b]==1)
return;//不访问无值结点和障碍物结点
/********修改当前结点上方结点********/
if(a-1>=0 && m[a-1][b]==0){//保证上方有结点且不是障碍物
if(v[a-1][b]==0 || v[a][b]+1<v[a-1][b])
v[a-1][b]=v[a][b]+1;
}
/********修改当前结点下方结点********/
if(a+1<Height && m[a+1][b]==0){//保证下方有结点且不是障碍物
if(v[a+1][b]==0 || v[a][b]+1<v[a+1][b])
v[a+1][b]=v[a][b]+1;
}
/********修改当前结点左方结点********/
if(b-1>=0 && m[a][b-1]==0){//保证左方有结点且不是障碍物
if(v[a][b-1]==0 || v[a][b]+1<v[a][b-1])
v[a][b-1]=v[a][b]+1;
}
/********修改当前结点右方结点********/
if(b+1<Width && m[a][b+1]==0){//保证右方有结点且不是障碍物
if(v[a][b+1]==0 || v[a][b]+1<v[a][b+1])
v[a][b+1]=v[a][b]+1;
}
}
void search(int direction,int **m,int **v)
{
int count;//上下遍历时记录行数,左右遍历时记录列数
/**********向下遍历整个图**********/
if(direction==down){
count=0;//记录行标
while(count<Height){
for(int i=0;i<Width;i++){//找到该行中第一个被访问过的点
if(v[count][i]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向左遍历
visit(count,j,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(count,k,m,v);
count++;//进入下一行
}
}
/**********向上遍历整个图**********/
if(direction==up){
count=Height-1;//记录行标
while(count>=0){
for(int i=0;i<Width;i++){//找到该行中第一个被访问过的点
if(v[count][i]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向左遍历
visit(count,j,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(count,k,m,v);
count--;//进入上一行
}
}
/**********向右遍历整个图**********/
if(direction==right){
count=0;//记录列标
while(count<Width){
for(int i=0;i<Height;i++){//找到该列中第一个被访问过的点
if(v[i][count]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向上遍历
visit(j,count,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(k,count,m,v);
count++;//进入右一列
}
}
/**********向左遍历整个图**********/
if(direction==left){
count=Width-1;//记录列标
while(count>=0){
for(int i=0;i<Height;i++){//找到该列中第一个被访问过的点
if(v[i][count]!=0)
break;
}
for(int j=i;j>=0;j--)//以刚才找到的点为中心向上遍历
visit(j,count,m,v);
for(int k=i+1;k<Width;k++)//以刚才找到的点为中心向右遍历
visit(k,count,m,v);
count--;//进入左一列
}
}
}
void back_check(int **m,int **v,int in_a,int in_b)//确保能够遍历到出口点
{
int direction;
if(v[in_a][in_b]==0){
direction=up;
search(direction,m,v);
direction=down;
search(direction,m,v);
direction=left;
search(direction,m,v);
direction=right;
search(direction,m,v);
}
}
void outputpath(int **v,int in_a,int in_b)
{
int a=in_a;
int b=in_b;
if(v[a][b]==0)
cout<<"没有通往出口的最短路径!!!"<<endl;
else{
cout<<"走出该迷宫的最短路径为:"<<endl;
while(v[a][b]!=1){
cout<<'('<<a+1<<','<<b+1<<')'<<"-->";
if(a-1>=0 && v[a-1][b]==v[a][b]-1){//上移
a=a-1;
continue;
}
if(a+1<Height && v[a+1][b]==v[a][b]-1){//下移
a=a+1;
continue;
}
if(b-1>=0 && v[a][b-1]==v[a][b]-1){//左移
b=b-1;
continue;
}
if(b+1<Width && v[a][b+1]==v[a][b]-1){//右移
b=b+1;
continue;
}
}
cout<<'('<<a+1<<','<<b+1<<')'<<endl;
}
}