⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 迷宫问题.txt

📁 本书主要内容包括经典电磁理论及其数学基础
💻 TXT
字号:
迷宫问题

class TMaze                                      //迷宫类
{
public:
 TMaze(){}                                       //构造函数                                        
 TMaze(char* fname);                     //构造函数,初始化
 void BFS();                                     //成员函数,广度优先搜索 
 void Back();                                    //成员函数,回溯法  
private:
 int *p,*q;                                        //数据成员,迷宫构造、访问标志   
 int row,col,last;                                 //数据成员,当前坐标,父结点指针                                  
 static int rows,cols,number,exitrow,exitcol,mark; //数据成员,迷宫入口、出口坐标,路径足迹
 static int d[];                                   //数据成员,位移坐标增量
 void Print();                                     //成员函数,打印迷宫
 void Print(TList<TMaze> L);                       //成员函数,打印BFS路径 
 bool Extend(int);                                 //成员函数,判断给定方向可否通过
};
//静态数据成员,可供全体对象共享
int TMaze::rows,TMaze::cols,TMaze::number;
int TMaze::exitrow,TMaze::exitcol,TMaze::mark;
int TMaze::d[]={0,1,0,-1,0};
//构造函数,从文件读入迷宫数据,初始化迷宫
TMaze::TMaze(char* fname)
{
 ifstream fin;
 fin.open(fname,ios::in | ios::nocreate);
 if(!fin)
 {
  cout<<"不能打开数据文件!"<<endl;
  return;
 }
 fin>>rows>>cols;                                  //读入迷宫行列数
 fin>>row>>col>>exitrow>>exitcol;                  //读入迷宫入口出口坐标                   
 number=rows*cols;                                 //存储单元总数
 p=new int[number];                                //申请迷宫数据存储单元
 q=new int[number];                                //申请迷宫各点访问标志存储单元 
 for(int i=0;i<number;i++)                         //读入迷宫数据  
 {
  fin>>p[i];
  q[i]=p[i];                                    //设置访问标志,0——通道,未访问,1——墙  
 } 
 fin.close();                                      //关闭文件
 last=0;                                           //入口的父结点 
}
//成员函数,打印迷宫结构 
void TMaze::Print()
{
 for(int i=0;i<number;i++)
 {
  cout<<setw(3)<<p[i];
  if((i+1)%cols==0)
   cout<<endl;
 }
 cout<<endl;
}
////成员函数,BFS找到的路径要从出口返回才能确定
void TMaze::Print(TList<TMaze> L)
{
 if(last==0)                                         //返回入口  
  return;                                         //结束
 else                                                //否则
 {          
  TMaze T=L.GetItem(last);                        //找到结点的父结点
  T.Print(L);                                     //递归 
  p[T.row*cols+T.col]=++mark;                     //设置足迹    
 }
}
//成员函数,判断给定方向是否可通过,不能则返回0,能则返回行位置
bool TMaze::Extend(int i)                               
{
 int newrow=row+d[i];                                 //方向i前进一步的新坐标
 int newcol=col+d[i+1];
 if(p[newrow*cols+newcol]==1 || q[newrow*cols+newcol]==1)//若该点是墙或已经经过
  return 0;                                           //不能向该方向前进  
 row=newrow;                                          //否则可前进,修改当前位置坐标
 col=newcol;
 q[newrow*cols+newcol]=1;                             //设置已访问标志
 return 1;                                            //返回可通过信息
}
//成员函数,用广度优先搜索搜索路径
void TMaze::BFS()                                         
{
 TMaze T=*this;                                        //中间对象变量
 TList<TMaze> L;                                       //设置队列
 L.InList(T);                                          //起始结点进入队列 
 p[row*cols+col]=mark=1;                               //起点足迹
 q[row*cols+col]=1;                                    //起点已被访问
 int head=0,tail=0;                                    //队列头和尾指针
 while(head<=tail)                                     //队列不空时循环
 {
  for(int i=0;i<4;i++)                              //顺序从东(0)、南(1)、西(2)、北(3)四个方向试探寻找通路 
  {
   T=L.GetItem(head);                            //从队列中取出头指针所指结点
   if(T.Extend(i))                               //如果在方向i可前进一步
   {
    T.last=head;                              //记录其父结点
    L.InList(T);                              //将新结点加入队列
    tail++;                                   //移动尾指针
   }
   if(T.row==exitrow && T.col==exitcol)          //如果该结点是出口
   {    
    T.Print(L);                               //递归找出路经 
    p[T.row*cols+T.col]=++mark;               //设置出口足迹
    T.Print();                                //输出包含路径的迷宫
    return;                                   //结束
   }
  }                                                 //一个结点的各个方向都已试探过
  head++;                                           //将队列头指针向后移,只想未检查的结点
 }
 cout<<"未找到通路。"<<endl;
}
//成员函数,回溯法搜索路径
void TMaze::Back()
{
 TMaze T=*this;                                        //中间对象变量
 TList<TMaze> L;                                       //设置堆栈  
 L.Push(T);                                            //起始结点进栈
 p[row*cols+col]=mark=1;                               //入口足迹
 q[row*cols+col]=1;                                    //入口已被访问
 while(L.Getlen()>0)                                   //当堆栈不空时循环
 {
  for(int i=0;i<4;i++)  //顺序从东(0)、南(1)、西(2)、北(3)四个方向试探寻找通路 
  {
   T=L.GetTop();                                 //取出栈顶元素 
   if(T.row==exitrow && T.col==exitcol)          //若该结点是出口
   {
    T.Print();                                //输出迷宫 
    return;                                   //结束 
   }
   if(T.Extend(i))                               //否则,如果在方向i可前进一步
   {
    p[T.row*cols+T.col]=++mark;               //设置该点足迹
    q[T.row*cols+T.col]=1;                    //设置该点已被访问
    L.Push(T);                                //将新结点入栈 
    break;                                    //不再检查其他方向
   }
  }
  if(i==4)                                          //若结点各个方向都不能前进
  {
   p[T.row*cols+T.col]=0;                        //恢复原来状态
   mark--;                                       //恢复足迹
   L.Pop();                                      //将该结点出栈,退回前一点
  }   
 }
 cout<<"找不到通路。"<<endl;
}

//简单的线性链表,既可作为队列,也可作为堆栈使用
//TList.h
template<class Type> class TList;

template<class Type> class TNode
{
 friend class TList<Type>;
 public:
  TNode(){Next=0;Type();}
 private:
  TNode<Type>* Next;
  Type Data;
};

template<class Type> class TList
{
 public:
  TList(){Last=0;Length=0;}
  int Getlen()const{return Length;}
  void InList(const Type& T);
  void Push(const Type& T);
  Type Pop();
  Type GetTop()const{return Last->Next->Data;}
  Type GetItem(int)const;
 private:
  TNode<Type>* Last;
  int Length;
};

template<class Type> void TList<Type>::InList(const Type& T)
{
 TNode<Type> *p=new TNode<Type>;
 p->Data=T;
 if(Last)
 {
  p->Next=Last->Next;
  Last=Last->Next=p;
 }
 else
  Last->Next=Last=p;
 Length++;
}

template<class Type> void TList<Type>::Push(const Type& T)
{
 TNode<Type>* p=new TNode<Type>;
 p->Data=T;
 if(Last)
 {
  p->Next=Last->Next; 
  Last->Next=p;  
 }
 else
  Last->Next=Last=p; 
 Length++;
}

template<class Type> Type TList<Type>::Pop()
{ 
 TNode<Type>* p=Last->Next;
 Type dat=p->Data;
 Last->Next=Last->Next->Next;
 Length--;
 delete p;
 return dat;
}

template<class Type> Type TList<Type>::GetItem(int k)const
{
 TNode<Type> *p=Last->Next;
 while(k-->0)
  p=p->Next;
 return p->Data; 
}

#include<iostream.h>
#include<iomanip.h>
#include<fstream.h>
#include<TList.h>
#include"TMaze.h"

//测试函数
int main()
{
 char f[]=".\\maze.txt";         //数据文件
 TMaze T(f);                        //初始化
 T.BFS();                              //广度优先搜索法
 //T.Back();                           //回溯法
 return 0;
}

//迷宫数据文件
//maze.txt
23 22 1 0 21 21                    //迷宫行列数、入口、出口坐标
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1
1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 0 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1
1 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1
1 0 1 1 1 0 1 0 1 1 0 0 0 1 0 1 1 1 1 1 0 1
1 0 1 0 1 1 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 1
1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 1 0 1 0 1 0 1
1 0 1 0 1 0 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 1 0 1
1 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 1
1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 0 0 1 1 1 0 1
1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 1 1 1 0 1
1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 0 0 0 1 1
1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1
1 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0 0 0 1
1 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 0 1 0 1 1
1 0 1 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 1 1
1 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 1 1
1 0 1 1 1 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 1 0 1 1 0 1 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

//BFS执行结果
  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
  1  2  0  0  0  1  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  1
  1  3  1  1  1  1  0  1  0  1  1  1  1  1  1  1  1  1  1  1  0  1
  1  4  5  6  7  8  0  1  0  0  0  1  0  0  0  0  0  0  0  0  0  1
  1  1  1  1  1  9  1  1  1  1  0  1  0  1  1  1  1  1  1  1  0  1
  1 14 13 12 11 10  1  0  0  0  0  1  0  1  0  0  0  0  0  0  0  1
  1 15  1  1  1  0  1  0  1  1  0  0  0  1  0  1  1  1  1  1  0  1
  1 16  1  0  1  1  1  0  1  0  1  1  0  1  0  1  0  0  0  1  0  1
  1 17  1  0  0  0  1  0  1  0  0  0  0  0  0  1  0  1  0  1  0  1
  1 18  1  0  1  0  0  0  1  0  1  1  0  1  0  1  0  1  0  1  0  1
  1 19  1  0  1  1  1  1  1  0  1  1  1  1  0  1  0  1  0  1  0  1
  1 20 21 22  1  0  0  1  0  0  0  0  0  0  1  1  0  1  0  0  0  1
  1  1  1 23  1  1  0  1  0  1  1  1  1  1  1  0  0  1  1  1  0  1
  1  0  0 24 25 26 27  1  0  1  0  0  0  0  0  0  1  1  1  1  0  1
  1  1  1  1  1  1 28  1  0  1  1  0  1  1  1  1  1  0  0  0  1  1
  1 34 33 32 31 30 29  0  0  0  1  0  1  0  0  0  0  0  1  0  1  1
  1 35  1  1  1  1  1  0  1  1  0  0  0  0  1  1  1  1  0  0  0  1
  1 36  0  0  0  0  1  0  1  1  1  1  1  1  1  1  1  0  1  0  1  1
  1 37  1  1  1  1  1  1 50 51 52  1 58 59 60 61  0  0  0  0  1  1
  1 38  0  0  0  0  0  1 49  1 53  1 57  1  1 62  1  1  1  1  1  1
  1 39  1  1  1  1  1  1 48  1 54 55 56  0  1 63  1  1  1  1  1  1
  1 40 41 42 43 44 45 46 47  1  0  1  1  0  1 64 65 66 67 68 69 71
  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  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
  1  2  0  0  0  1 11 12 13  1  0  0  0  0  0  0  0  0  0  0  0  1
  1  3  1  1  1  1 10  1 14  1  1  1  1  1  1  1  1  1  1  1  0  1
  1  4  5  6  7  8  9  1 15 16 17  1  0  0  0  0  0  0  0  0  0  1
  1  1  1  1  1  0  1  1  1  1 18  1  0  1  1  1  1  1  1  1  0  1
  1  0  0  0  0  0  1  0  0  0 19  1  0  1 29 30 31 32 33 34 35  1
  1  0  1  1  1  0  1  0  1  1 20 21 22  1 28  1  1  1  1  1 36  1
  1  0  1  0  1  1  1  0  1  0  1  1 23  1 27  1 49 48 47  1 37  1
  1  0  1  0  0  0  1  0  1  0  0  0 24 25 26  1 50  1 46  1 38  1
  1  0  1  0  1  0  0  0  1  0  1  1  0  1  0  1 51  1 45  1 39  1
  1  0&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -