深度优先——迷宫算法

来源:互联网 发布:鸠摩智和金轮法王知乎 编辑:程序博客网 时间:2024/05/18 13:24

   前一阵一直想写这个程序,一直没有有效的解决保存路径的问题。现在想到的办法是用队列保存每个节点的下表来表示路径。

 这个算法解决问的问题是: 建一个迷宫(用矩阵表示m行,n列)期中矩阵的左上角(坐标为(0,0的点)为入点,找寻到所有到(m-1,n-1)的所有不重复路径,并打印出来。

代码注释如下

#include<iostream>
#include<deque>
using namespace std;
deque<int> Q;//用于保存路径的队列
struct node{//用于创建矩阵的结点
 int x,y;//每个节点的下标
 char color;//节点的颜色 (H表示可以通过,B表示墙)
};
void print();//用于打印路径的函数
bool f(int i,int j,int m,int n);//判断是否超越迷宫的边界
void search(node**p,int i,int j,int m,int n);//深度优先搜索
void main(){
 int m,n;
 cout<<" 输入矩阵的情况:"<<endl;
 cin>>m>>n;
 node**p=new node*[m];
 for(int i=0;i<m;i++)
    p[i]=new node[n];
   for(i=0;i<m;i++){//初始化迷宫矩阵
     for(int j=0;j<n;j++)
      cin>>p[i][j].color;
         p[i][j].x=i;
      p[i][j].y=j;
   }
   Q.push_back(0);//将入点坐标压入队列
   Q.push_back(0);
   search(p,0,0,m,n);//搜索
}
void print(){
 deque<int>::iterator p;
 int count=0;
 for(p=Q.begin();p!=Q.end();p++){
  count++;
  cout<<*p;
  if(count%2==0) cout<<endl;
 }

bool f(int i,int j,int m,int n){
  if(i>=m||i<0) return false;
  if(j<0||j>=n) return false;
  return true;
}
void search(node**p,int i,int j,int m,int n){
    deque<int>::iterator t;
 if(i==m-1&&j==n-1){//若是出点 打印路径
  print();
  return; //返回至上一层递归
 }
 if(f(i,j-1,m,n)&&p[i][j-1].color=='H'){//若左边可以到达
  p[i][j].color='B';//令此处为墙
  t=Q.end();//令t为当前队列末端
  Q.push_back(i);//向左移动并保存路径
  Q.push_back(j-1);
  search(p,i,j-1,m,n);//继续搜索
        p[i][j].color='H';//回到原处
  Q.erase(t,Q.end()); //删除路径记录
 }
    if(f(i,j+1,m,n)&&p[i][j+1].color=='H'){//若右边可以到达
             p[i][j].color='B';
             t=Q.end();
    Q.push_back(i);
    Q.push_back(j+1);
    search(p,i,j+1,m,n);
             p[i][j].color='H';
    Q.erase(t,Q.end());
    }
 if(f(i-1,j,m,n)&&p[i-1][j].color=='H'){//若上边可以到达
  p[i][j].color='B';
        t=Q.end();
  Q.push_back(i-1);
  Q.push_back(j);
  search(p,i-1,j,m,n);
     p[i][j].color='H';
  Q.erase(t,Q.end());
 }
 if(f(i+1,j,m,n)&&p[i+1][j].color=='H'){//若下边可以到达
        p[i][j].color='B';
        t=Q.end();
  Q.push_back(i+1);
  Q.push_back(j);
  search(p,i+1,j,m,n);
  p[i][j].color='H';
  Q.erase(t,Q.end());
 }
}

算法核心可以简述为  把当前位置设置为“墙”的目的是:如果找到了终点,那么会得到答案,如果是堵死的,那么这条路不可走,相当于墙,直接堵死以免在之后的搜索中重复

原创粉丝点击