• 用递归实现求一个迷宫是否有通路


    今天最终把昨天下午没写出来的迷宫求是否有通路的cpp写出来了

    使用递归实现的,只是算法的质量不怎么样,使用穷举法实现的。

    在网上搜了一下,发现还有非常多的更优的算法,哈哈,只是怎么说都是自己一个个地代码敲出来的。

    特点是发如今linux以下调试真的有时候自己会崩溃,还好终于还是搞出来了。

    哈哈,发上来给类似我这样的的算法新手来一起分享一下;

    路径就记录在栈里面,须要得出详细路径的能够小改一下即可了。

    findRoad.cpp

    //迷宫求解问题思路
    //1.用一个矩阵来表示迷宫,即n*m数组
    //用穷举法实现;即从入口出发,顺着某一个方向向前探索,若能走通,则继续往前走;
    //若到了某一点走不通,则标记该点为不可达
    //否则原路返回,换一个方向再继续探索
    //详细的请看算法解释
    #include <iostream>
    using namespace std;
    #include "stack.cpp"
    struct box{
    	bool status;//用于推断该处是否可通
    	int direct;//用于标记在这里向哪个方向探索过了,
    	//1234分别代表向左上右下的顺序探索,即顺时针方向
    };
    struct posType//用于记录某一点的坐标值
    {
    	int x;
    	int y;
    };
    bool isEqueal(posType a,posType b)//跟arriived一样,只是名字变了而已
    {
    	if(a.x==b.x&&a.y==b.y)
    		return true;
    	return false;
    
    }
    bool arrived(posType start,posType end)//推断是否已经到达出口
    {
    	if(start.x==end.x&&start.y==end.y)
    		return true;
    	return false;
    
    };
    static mStack<posType> ms;//用于存放经过的路径
    const int MAXLINE=5;//须要的时候再改
    const int MAXROW=5;
    bool findRoad(box (*arr)[MAXROW],posType start,posType end)//注意二维数组的指针表示
    {
    	int x=start.x;
    	int y=start.y;
    	if(arrived(start,end))//假设到达
    		return true;
    	//还会有以下这样的情况
    	//应该这样表达才对arr+start.x*MAXROW+start.y)->status
    	//而不是(*arr+i)+j
    	if((*arr+x*MAXROW+y)->status==false)//假设仅剩该点且该点四周都不可达,则路到了尽头!!
    		return false;
    	posType temp;
    	if(ms.isEmpty())	//假设栈空
    		ms.Push(start);		//将当前位置入栈
    	else 	//推断是否是上一个点,避免反复入栈
    	{
    		ms.GetTop(temp);
    		if(!isEqueal(temp,start))
    			ms.Push(start);
    	}
    	
    	
    	switch((*arr+x*MAXROW+y)->direct)//检測往哪个方向走过了
    	{
    		//derect=0代表未向不论什么方向探索过,应向左探索
    		//=1代表要向上探索
    		case 0:if(y-1>-1&&(*arr+x*MAXROW+y-1)->status)//向左方探索,假设没有越界而且左方是可达的
    			{
    					//posType newStart(x-1,y);//以左方作为新起点
    					posType newStart;
    					newStart.x=x;
    					newStart.y=y-1;
    					(*arr+x*MAXROW+y)->direct=1;//应该是该点=1;该点探索过了而不是下一点
    					//arr[newStart.x][newStart.y].direct=1;//探索的方向+1
    					findRoad(arr,newStart,end);//以新起点開始探索
    			}
    			else//倘若数组越界了,或者左方不可达,则向上探索
    			{
    				(*arr+x*MAXROW+y)->direct=1;//令其=1,再递归调用
    				findRoad(arr,start,end);//起点不变
    			};break;
    		case 1:if(x-1>-1&&(*arr+(x-1)*MAXROW+y)->status)//向上方探索,假设没有越界而且上方是可达的
    				{
    //					posType newStart(x,y-1);//以该起点作为新点
    					posType newStart;
    					newStart.x=x-1;
    					newStart.y=y;
    					(*arr+x*MAXROW+y)->direct=2;//应该是该点=1;该点探索过了而不是下一点
    					//arr[newStart.x][newStart.y].direct=2;//探索的方向=2
    					findRoad(arr,newStart,end);//以新起点開始探索
    				}
    				else//倘若数组越界了,则向上探索
    				{
    					(*arr+x*MAXROW+y)->direct=2;//令其=2,再递归调用,即指示其向下一个方向探索
    					findRoad(arr,start,end);//起点不变
    				};break;
    		case 2:	if(y+1<MAXROW&&(*arr+x*MAXROW+y+1)->status)//向右方探索,假设没有越界而且右方是可达的
    				{
    					//posType newStart(x+1,y);//以该起点作为新点
    					posType newStart;
    //					newStart.x=x+1;
    					newStart.x=x;//向右应该是y+1
    					newStart.y=y+1;
    					(*arr+x*MAXROW+y)->direct=3;
    					//arr[newStart.x][newStart.y].direct=3;//探索的方向=3
    					findRoad(arr,newStart,end);//以新起点開始探索
    				}
    				else//倘若数组越界了或者不可达,则向下探索
    				{
    					(*arr+x*MAXROW+y)->direct=3;//令其=3,再递归调用,即指示其向下一个方向探索
    					findRoad(arr,start,end);//起点不变
    				};break;
    		case 3:	if(x+1<MAXLINE&&(*arr+(x+1)*MAXROW+y)->status)//向下方探索,假设没有越界而且下方是可达的
    				{
    					//posType newStart(x,y+1);//以该起点作为新点
    					posType newStart;
    					newStart.x=x+1;
    					newStart.y=y;
    					(*arr+x*MAXROW+y)->direct=4;
    					//arr[newStart.x][newStart.y].direct=4;//探索的方向=3
    					findRoad(arr,newStart,end);//以新起点開始探索
    				}
    				else//倘若数组越界了或者不可达,更改此点为不可达
    				{
    					(*arr+x*MAXROW+y)->direct=4;//令其=3,再递归调用,即指示其向下一个方向探索
    					findRoad(arr,start,end);//起点不变
    				};break;
    		case 4:	(*arr+x*MAXROW+y)->status=false;//当四个方向都探索完了之后,均没有通路时,标记该点为不可达状态
    				
    				posType t;//将当前点出栈
    				ms.Pop(t);//
    				if(ms.isEmpty())//假设此时栈已经空了,说明没有路能够回头了,路不通
    					return false;
    				ms.Pop(start);//令上一路径为起点,递归找路
    				findRoad(arr,start,end);
    				break;
    	};
    };
    
    

    stack.cpp

    //用于实现栈的操作
    #include <iostream>
    using namespace std;
    //const int MAX=100;//栈最大长度值为100,用数组实现栈
    //写成模板类是为了方便我以后使用
    template <class T>
    class mStack{
    	private:
    		enum {MAX=1000};
    		T arr[MAX];
    		int Size;
    		int top;//用于指示栈顶位置
    	public:
    		mStack(	)//构建空栈
    		{
    		  top=-1;//下标为-1则为空栈
    		  Size=0;
    		}
    		bool isEmpty()
    		{
    			return top==-1;
    		}
    		bool isFull()
    		{
    			return top==MAX-1;
    		}
    		bool Push(T &item)
    		{
    			if(isFull())
    			{
    				cout<<"stack is full!"<<endl;
    				return false;
    			}
    			//++top;
    			//arr[++top]=item;
    			arr[++top]=item;//由于下标从-1開始,使用前+1
    			//cout<<"this "<<top<<" item push values is :"<<arr[top]<<endl;
    			Size++;
    			return true;
    		}
    		bool Pop(T &item)
    		{
    			if(isEmpty())
    			{
    				cout<<"stack is empty!"<<endl;
    				return false;
    			}
    			item=arr[top--];//由于下标从-1開始,top指向当前最后一个元素,使用后-1
    			//cout<<"this "<<top<<" item pop values is :"<<arr[top]<<endl;
    			Size--;
    			return true;
    		}
    		bool GetTop(T &item)
    		{
    			if(!isEmpty())
    			{
    				item=arr[top];
    				return true;
    			}			
    			return false;
    		}
    		int size()
    		{
    			return Size;
    		}
    
    };
    
    test.cpp

    #include <fstream>
    #include <cstdlib>
    #include <ctime>
    #include "all.cpp"
    const int MAXL=5;
    const int MAXR=5;
    
    int main()
    {
    	ofstream fout;//("test1.txt");//,ios_base::app);//,ios_base::app);
    	fout.open("test1.txt",ios_base::app);
    	
    	if(!fout.is_open())
    		cerr<<"open failer!"<<endl;
    	
    	//box (*b)[MAXR];
    	box (*b)[MAXR]=new box[MAXL][MAXR];
    	ifstream fin("tx.txt");//从文件里读取迷宫
    	if(!fin.is_open())
    		cerr<<"fin open failure!"<<endl;
    
    	for(int i=0;i<MAXLINE;i++)
    		{
    		for(int j=0;j<MAXROW;j++)
    			{
    				int num;
    				fin>>num;
    				//*(*(b+i)+j)=new box;
    				if(num==1)
    					(*(b+i)+j)->status=false;//给迷宫里的box赋值
    					//(*(ar+i)+j)->status=false;
    				else
    					(*(b+i)+j)->status=true;
    				
    					(*(b+i)+j)->direct=0;
    			}
    		}
    	
    	fin.close();
    	posType start;
    	start.x=0;
    	start.y=1;
    	
    	posType end;
    	end.x=0;
    	end.y=3;
    	
    	(*(b+start.x)+(start.y))->status=true;
    	(*(b+end.x)+end.y)->status=true;
    		
    	for(int i=0;i<MAXLINE;i++)
    	{
    		
    		for(int j=0;j<MAXROW;j++)
    		{
    			if((*(b+i)+j)->status)
    				fout<<"0 ";
    			else
    				fout<<"1 ";
    		}	
    		fout<<endl;
    	}	
    	fout<<endl<<endl;
    	fout.close();	
    	
    
    	if(findRoad(b,start,end))
    		cout<<"has load!"<<endl;
    	else
    		cout<<"no load "<<endl;	
    	
    }

    tx.txt

    //能够自己设置迷宫路径和出发点以及出口

    1 0 1 0 1
    0 0 1 0 0
    0 0 1 0 0
    0 0 1 0 1
    1 0 0 0 0


  • 相关阅读:
    windows下安装mysql教程
    git基本操作
    JDK8,Optional
    重新安装MySQL 8出现的问题
    HTML5学习:缩略图
    HTML5学习:表格
    MySQL常用命令
    Django学习:创建admin后台管理站点
    Django学习:连接Mysql数据库
    Django学习:创建第一个app
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4271932.html
Copyright © 2020-2023  润新知