基於棧實現解決迷宮問題
ios
棧是一種很是常見的數據結構,在計算機領域被普遍應用,例如操做系統會給每一個線程建立一個棧用來存儲函數調用時各個函數的參數,返回地址及臨時變量等,棧的特色是後進先出,即最後被壓入(push)棧的元素會第一個被彈出(pop)。
數組
以下所示給定一個迷宮(「1」表示此路不通,「0」表示此路經過),那麼給定一個入口點,如何找到一條通路呢?若是一個迷宮的規模很大,又如何實現呢?給出兩種方法:數據結構
第一種,能夠用一個二維數組來保存迷宮,可是若是迷宮的規模太大,或者咱們頻繁的更改迷宮時,使用二維數組顯然不夠機智。ide
第二種,採用文件的方式來保存迷宮,程序中只用實現讀取文件的操做便可,這樣便於之後對程序的維護。先將迷宮的入口點壓人棧,再對這個點的上、下、左、右方向進行判斷,看可否有經過的點,假若沒有,則迷宮中沒有一條能夠經過的路徑,若是存在,則將這個點也壓人棧中,循環下去,直到找到沒有能夠繼續進行的點,此時須要「回溯」,即倒回之前走過的點,進而判斷有沒有剛纔沒有走過且能夠經過的點,仍存在,再次進行剛纔的壓棧操做,直到走出迷宮爲止。不然沒有通路。函數
代碼以下:spa
#pragma once操作系統
#define N 10線程
#include<iostream>3d
#include<assert.h>blog
#include <stack>
using namespace std;
//使用靜態數組
struct Pos //標記點的位置座標
{
int _row;
int _col;
};
//void GetMaze(int a[][N], int n)
void GetMaze(int* a, int n)//獲取文件中的迷宮
{
assert(a);
FILE* open = fopen("F:\\比特有關書籍\\數據結構\\MazeMap.txt", "r");
assert(open);//判斷打開文件是否成功
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; )
{
char ch = fgetc(open);
if (ch == '0' || ch == '1')
{
a[i*n+j] = ch - '0';
++j;//爲了防止迷宮中行和列之間的距離
}
else
{
continue;
}
}
}
fclose(open);
}
void PrintMaze(int* a, int n)//打印迷宮
{
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cout<<a[i*n+j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
bool CheckIsAccess(int* a, int n, Pos next)//檢查迷宮結點的下一個路徑上的結點
{
assert(a);
if (next._row >= 0 && next._row < n
&& next._col >=0 && next._col < n
&& a[next._row*n+next._col] == 0)
{
return true;
}
else
{
return false;
}
}
//entry 爲迷宮的入口位置,path用於保存迷宮的通路
//判斷迷宮中是否存在一條通路
bool MazePath(int* a, int n, const Pos& enrty,
stack<Pos>& path)
{
Pos cur = enrty;
path.push(cur);
while (!path.empty())
{
// 是否已經到出口
if (cur._row == n-1)
{
return true;
}
a[cur._row*n + cur._col] = 2;//將壓棧後的位置內容進行更改
Pos next = cur;
// 上
next._row--;
if(CheckIsAccess(a, n, next))
{
cur = next;
path.push(cur);
continue;
}
// 右
next = cur;
next._col++;
if(CheckIsAccess(a, n, next))
{
cur = next;
path.push(cur);
continue;
}
// 下
next = cur;
next._row++;
if(CheckIsAccess(a, n, next))
{
cur = next;
path.push(cur);
continue;
}
// 左
next = cur;
next._col--;
if(CheckIsAccess(a, n, next))
{
cur = next;
path.push(cur);
continue;
}
cur = path.top();
path.pop();
}
return false;
}
void TestMaze()
{
int a[N][N] = {};
GetMaze((int*)a, N);
PrintMaze((int*)a, N);
stack<Pos> path;
Pos enrty = {2,0};
bool ret = MazePath((int*)a, N, enrty, path);
cout<<"是否有通路:"<<" "<<ret<<endl;
PrintMaze((int*)a, N);
}