假设有这样一个迷宫,以数字0代表通路,数字1代表不通
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
0 0 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 0 0 0
1 1 0 0 0 0 0 0 1 1
1 1 0 1 1 1 1 0 1 1
1 1 0 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 0 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 1 1 1
1 1 0 1 1 1 1 0 0 0
1 1 0 0 0 0 0 0 1 1
1 1 0 1 1 1 1 0 1 1
1 1 0 1 1 1 1 0 1 1
1 1 1 1 1 1 1 1 1 1
问题:从坐标为(2,0)处进入判断是否有通路,如果有则将其中的那条通路用数字2代替;
对于问题1首先,我们解决迷宫问题的方法是用一种“试探”的思想 ,每当我们要走出一步的时候都要试探上下左右四个方向是否为0,然后,如果有0则向这个方向挪动一次并重复上面的步骤,如果没有0我们就要“返回”到上一步,直至
返回到起点。
上面提到了两个关键字“试探”和“返回”,试探很简单实现,就让你的x或y坐标动一下就可以了,而要做到“返回”,我们
必须要有一种可以存储每一步的数据结构,并且可以随时删除掉现在的坐标,栈就恰恰满足这个条件。
返回到起点。
上面提到了两个关键字“试探”和“返回”,试探很简单实现,就让你的x或y坐标动一下就可以了,而要做到“返回”,我们
必须要有一种可以存储每一步的数据结构,并且可以随时删除掉现在的坐标,栈就恰恰满足这个条件。
作为一名数据结构初学者为了更深的了解栈的原理,这里我们用自己实现的栈来解决这个问题。
#include<iostream>
#include<assert.h>
#include<fstream>
using namespace std;
#define N 10
//用顺序表实现栈,因为栈的操作都是push和pop还有top,所以直接用顺序表的size和capacity操作
template<typename T>
class Stack
{
public:
Stack(int size=0,int capacity=10)
:_size(size)
,_capacity(capacity)
,_data(new T[_capacity])
{}
~Stack()
{
delete[] _data;
}
bool empty()
{
if(_size==0)
return true;
return false;
}
void CheckCapacity(int n)
{
if(_size+n>=_capacity)//每次空间不够用的时候就重新开辟一块两倍的空间再将原来的内容拷贝进去
{
int newcapacity=_capacity*2+10;
T* tmp=new T[newcapacity];
memcpy(tmp,_data,_size*sizeof(T));
_data=tmp;
_capacity=newcapacity;
}
}
void Push(T data)
{
CheckCapacity(sizeof(T));
_data[_size++]=data;
}
void Pop()
{
if(_size==0)
return;
else
{
_size--;
}
}
T& top()
{
assert(_size!=0);
return _data[_size-1];//注意[]里面是size-1,因为每次push 后_size都会++
}
void display()
{
int size=_size;
while(size)
{
cout<<_data[size-1]<<endl;//注意[]里面是size-1,因为每次push 后_size都会++
size--;
}
}
private:
int _size;
int _capacity;
T* _data;
};
void test1()
{
Stack<int> st1;
st1.Push(1);
st1.Push(2);
st1.Push(3);
st1.Push(4);
st1.display();
cout<<endl;
cout<<st1.top()<<endl;
st1.Pop();
st1.display();
st1.Pop();
st1.Pop();
st1.display();
st1.Pop();
st1.display();
}
void InitMazemap(int arr[][N])
{
FILE* fout=fopen("mazemap.txt","r");//这里我们要提前定义一个"mazemap.txt"文件,将“地图”写好
assert(fout);
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
fscanf(fout,"%d",&arr[i][j]);
}
fscanf(fout,"\n");
}
fclose(fout);
}
void printarr(int arr[][N])
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
}
struct Pos
{
int _row;
int _col;
Pos(int row=0,int col=0)
:_row(row)
,_col(col)
{}
};
bool GetPath(int* maze,int rows,int cols,Stack<Pos>&s,Pos entry)
{
s.Push(entry);
while(!s.empty())
{
Pos cur=s.top();
maze[cur._row*cols+cur._col]=2;//每走一步将这步置为2
if((cur._row==rows-1)||(cur._col==cols-1))
return true;
//试探上面
if((cur._row-1>=0)&&(maze[(cur._row-1)*rows+cur._col]==0))
{
cur._row-=1;
s.Push(cur);
continue;
}
//试探下面
if((cur._row+1<=rows-1)&&(maze[(cur._row+1)*rows+cur._col]==0))
{
cur._row+=1;
s.Push(cur);
continue;
}
//试探左面
if((cur._col-1>=0)&&(maze[cur._row*rows+cur._col-1]==0))
{
cur._col-=1;
s.Push(cur);
continue;
}
//试探右面
if((cur._col+1<=cols-1)&&(maze[cur._row*rows+cur._col+1]==0))
{
cur._col+=1;
s.Push(cur);
continue;
}
s.Pop();
}
return false;
}
void test()
{
int arr[N][N];
InitMazemap(arr);
}
int main()
{
int maze[N][N];
InitMazemap(maze);
printarr(maze);
Stack<Pos> paths;
cout<<""<<GetPath((int* )maze,N,N,paths,Pos(2,0))<<endl;
printarr(maze);
getchar();
return 0;
}