您的位置:首页 > 其它

迷宫求解——附栈的实现

2016-09-16 15:26 197 查看
今天我们来完成一个简单的迷宫,首先我们需要一个迷宫地图在文件中,方便我们在文件中读取它。这是地图:



然后我们就进行读取地图,并保存地图到数组里面,这样很方便给出坐标。

接下来我们就要考虑怎么走了,其实很简单,我们只需让当前位置经行查找,上下左右只要是通路就移动到下一个位置,直到找到出口。

那如果走到死胡同了该如何,其实也很容易,这里我们就需要运用回溯法来解决问题。

那么什么事回溯法呢?

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。


当我们走到死路后就退回到上一个位置,继续判断,直到有一个方向是通路就继续走。

完成回溯法就需要用到我们的栈来实现,栈的特点就是在尾部插,尾部删,我们每次走一步就push进去一个数据,当需要退回时就pop一个出来。

这里需要用到栈,我们就自己来实现一把。

<strong>template<typename T>
class Stack
{
public:
Stack()
:_capacity(0)
, _size(0)
, _arr(NULL)
{}
~Stack()
{
delete[] _arr;
_size = 0;
_capacity = 0;
_arr = NULL;
}
void Push(const T& data);
void Pop();
T Top();
int Size();
bool Empty();
private:
void CheckCapacity()
{
if (_size >= _capacity)
{
int NewCapacity = _capacity * 2 + 1;
T* tmp = new T[NewCapacity];
for (int i = 0; i < _size; i++)
{
tmp[i] = _arr[i];
}
delete[] _arr;
_arr = tmp;
_capacity = NewCapacity;
}
}
private:
T* _arr;
int _capacity;
int _size;
};

template<typename T>
bool Stack<T>::Empty() //判断栈是否为空
{
if (_size == 0)
return true;
else
return false;
}

template<typename T>
void Stack<T>::Push(const T& data) //进栈
{
CheckCapacity();
_arr[_size++] = data;
}

template<typename T>
void Stack<T>::Pop() //出栈
{
assert(_size>0);
--_size;
}

template<typename T>
T Stack<T>::Top() //返回栈顶元素
{
return _arr[_size - 1];
}

template<typename T>
int Stack<T>::Size() //栈的大小
{
return _size;
}
</strong>当我们每走一步就把走过的路置为2,方便判断。
下面就是代码实现:

#include<iostream>
#include<cassert>
using namespace std;

template<typename T>
class Stack
{
public:
Stack()
:_capacity(0)
, _size(0)
, _arr(NULL)
{}
~Stack()
{
delete[] _arr;
_size = 0;
_capacity = 0;
_arr = NULL;
}
void Push(const T& data);
void Pop();
T Top();
int Size();
bool Empty();
private:
void CheckCapacity()
{
if (_size >= _capacity)
{
int NewCapacity = _capacity * 2 + 1;
T* tmp = new T[NewCapacity];
for (int i = 0; i < _size; i++)
{
tmp[i] = _arr[i];
}
delete[] _arr;
_arr = tmp;
_capacity = NewCapacity;
}
}
private:
T* _arr;
int _capacity;
int _size;
};

template<typename T>
bool Stack<T>::Empty() //判断栈是否为空
{
if (_size == 0)
return true;
else
return false;
}

template<typename T>
void Stack<T>::Push(const T& data) //进栈
{
CheckCapacity();
_arr[_size++] = data;
}

template<typename T>
void Stack<T>::Pop() //出栈
{
assert(_size>0);
--_size;
}

template<typename T>
T Stack<T>::Top() //返回栈顶元素
{
return _arr[_size - 1];
}

template<typename T>
int Stack<T>::Size() //栈的大小
{
return _size;
}

#define N 10
struct POS
{
POS(const int& row=0,const int col=0)
:_row(row)
,_col(col)
{}
size_t _row;
size_t _col;
};

void Getmaze(int *arr) //从文件中读取地图,保存在数组里
{
FILE* maze= fopen("MazeMap.txt","r");
assert(maze!=NULL);
int i=0,j=0;
for (i=0;i<N;i++)
{
for (j=0;j<N;)
{
char c=fgetc(maze);
if (c=='0'||c=='1')
{
arr[i*N+j]=c-'0';
j++;
}
continue;
}
}
fclose(maze);
}

void Printmaze(int *arr) //打印地图
{
for (int i=0;i<N;i++)
{
for (int j=0;j<N;j++)
{
cout<<arr[i*N+j]<<" ";
}
cout<<endl;
}
}

bool Checkpath(int *maze, POS &next) //检查下个路是否是通路
{
if (next._col < N && next._row < N
&& next._col >= 0 && next._row >= 0
&& (maze[next._row*N + next._col] == 0))
return true;
else
return false;
}
bool Getpath(int *maze, int row, int col, Stack<POS> &path, POS enter)
{
POS cur = enter;
POS next;
path.Push(cur);
while (!path.Empty())
{
if (cur._row != enter._row&&cur._col != enter._col && (cur._row == row - 1 || cur._row == 0 || cur._col == col - 1))
{
maze[cur._row*N + cur._col] = 2; //走过的路置为2
return true;

}

maze[cur._row*N + cur._col] = 2;

//右
next = cur;
++next._col;
if (Checkpath(maze, next))
{
cur = next;
path.Push(cur);
continue;
}

//左
next = cur;
--next._col;
if (Checkpath(maze, next))
{
cur = next;
path.Push(cur);
continue;
}

//上
next = cur;
--next._row;
if (Checkpath(maze, next))
{
cur = next;
path.Push(cur);
continue;
}

//下
next = cur;
++next._row;
if (Checkpath(maze, next))
{
cur = next;
path.Push(cur);
continue;
}
cur = path.Top();
path.Pop();
}
return false;
}
void test()
{
Stack<POS> path;
int maze

;
Getmaze((int *)maze);
Printmaze((int *)maze);
cout << endl;
Getpath((int *)maze, N, N, path, POS(2, 0));
cout << "找到出口后:" << endl;
Printmaze((int *)maze);

}

int main()
{
test();
system("pause");
return 0;
}

到此迷宫的问题就完了。
这是运行后的结果:




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  迷宫 搜索 回溯法