迷宮問題【資料結構實驗報告】
資料結構實驗報告
實驗名稱:實驗二 迷宮問題
學號:***
姓名:gnosed
實驗日期:2017.10.23
一、實驗目的
1、瞭解回溯法在求解迷宮問題中的應用
2、進一步掌握棧的使用
二、實驗具體內容
1、實驗題目1:
(1)題目
用回溯法求解迷宮問題,可以用一個棧儲存探索的序列。並且在該迷宮的行走中,站在一點可以有八個方向選擇。
比如如下的迷宮
Enter-> 0 1 1 1 0 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0
0 1 0 1 1 0 0 1 0 0
0 1 0 0 1 0 1 1 0 0
0 1 0 0 1 0 1 1 0 0
1 1 1 0 1 0 1 0 0 0
0 0 1 0 0 0 1 0 1 1
0 0 1 0 0 0 1 0 1 1
0 1 1 0 1 0 1 0 0 0
0 0 0 0 1 0 1 1 0 0 --> EXIT
下面是可能的路徑(注意:從入口到出口可能有多條路徑,優先選擇的方向不同,路徑可能也不一樣!)
Path: ( maze[0][0], maze[1][0],maze[1][1], maze[1][2], maze[2][2],
maze[3][2], maze[3][3], maze[4][3],maze[5][3], maze[6][3],
maze[6][4], maze[6][5], maze[5][5],maze[4][5], maze[3][5],
maze[2][5], maze[2][6], maze[1][6],maze[0][6], maze[0][7],
maze[0][8], maze[1][8], maze[2][8],maze[3][8], maze[4][8],
maze[5][8], maze[5][7], maze[6][7],maze[7][7], maze[8][7],
maze[8][8], maze[8][9], maze[9][9])
Enter-> X 1 1 1 0 0 X---X---X 0
X---X---X 1 0 0 X 1 X 0
0 1 X 1 1 X---X 1 X 0
0 1 X---X 1 X 1 1 X 0
0 1 0 X 1 X 1 1 X 0
1 1 1 X 1 X 1 X---X 0
0 0 1 X---X---X 1 X 1 1
0 0 1 0 0 0 1 X 1 1
0 1 1 0 1 0 1 X-- X-- X
0 0 0 0 1 0 1 1 0 X --> EXIT
(2)分析
規定:
1) 迷宮左上角第一個位置為入口,右下角第一個位置為出口。
2) 探索的方向為從上按順時針旋轉,上下左右四個方向。
3) 輸入:m,n和m*n個迷宮狀態,0表示通路,1表示有牆。
4) 輸出:若找到走通迷宮的路徑,輸出路徑的各步的位置。否則,提示找不到。
資料結構:
1) 用二維陣列MAZE[m][n] 來表示迷宮的狀態,0表示通路,1表示有牆,2表示已經走過。
2) 用STL的棧儲存走過的路徑,壓棧表示進入下一步,退棧表示返回上一步。每個棧元素是由當前位置座標。
演算法過程:
從入口位置開始,將其入棧。
1)取棧頂元素值(不出棧),
2)按規定方向判斷下一步的位置,即除了原走來的方向,判斷其餘三個方向是否有通路,
3)若發現一個(若第一個位置已走過,則判斷下一個)通路的位置,將其入棧;
4)若三個方向都是牆,則出棧。
5)若發現出口,輸出路線。若棧空,提示沒有路線。若未發現出口而且棧不為空,則重複1)2)3)4)。
(3)實驗程式碼
原始碼:
#include <iostream>
#include <stack>
using namespace std;
const int maxm=100,maxn=100;
int MAZE[maxm][maxn],m,n;
struct pos{
int i,j;
};
void create(){
for(int i=0;i<m;i++)
for(int j=0;j<n;j++){
int t;cin>>t;
MAZE[i][j]=t;
}
}
struct pos Move(struct pos curr){
/*判斷是否有通路,有則返回通路位置,無則返回原來位置
重複問題:
若何判斷原來方向
若何記錄哪個位置是第幾次走*/
struct pos next=curr;
int x=curr.i,y=curr.j;
//向上
if(!MAZE[x-1][y]&&(x-1)>=0&&
MAZE[x-1][y]!=2){
next.i=x-1;//只有x座標改變
MAZE[x-1][y]=2;//標記將要行走
return next;//返回要下一步的位置
}//向右
else if(!MAZE[x][y+1]&&(y+1)<n&&
MAZE[x][y+1]!=2){
next.j=y+1;
MAZE[x][y+1]=2;
return next;
}//向下
else if(!MAZE[x+1][y]&&(x+1)<m&&
MAZE[x+1][y]!=2){
next.i=x+1;
MAZE[x+1][y]=2;
return next;
}//向左
else if(!MAZE[x][y-1]&&y-1>=0&&
MAZE[x][y-1]!=2){
next.j=y-1;
MAZE[x][y-1]=2;
return next;
}
return curr;//無路,返回原來的位置
}
void findPath(){
stack<struct pos> Path;
struct pos curr,nex;
curr.i=0;curr.j=0;
Path.push(curr);//入口入棧
MAZE[0][0]=2;//標記已走過
while(!Path.empty()){//5)
curr=Path.top();//1)
// cout<<curr.i<<" "<<curr.j<<endl;
nex=Move(curr);//2)特別注意重複的問題和邊界處理問題
if(!(curr.i==nex.i&&curr.j==nex.j))//3)發現通路
Path.push(nex);
else
Path.pop();//4)未發現通路
if(nex.i==m-1&&nex.j==n-1){//5)
struct pos route[Path.size()];
int z=0;
while(!Path.empty()){
curr=Path.top();
route[z++]=curr;
Path.pop();
}
for(int k=z-1;k>=0;k--){
cout<<"("<<route[k].i<<","<<route[k].j<<")";
if(k%5==0) cout<<endl;
if(k) cout<<"->";
}
return ;
}
}
cout<<"NO Path!"<<endl;
}
int main(){
cin>>m>>n;
create();
findPath();
return 0;
}
測試資料:
Input
10 10
0 1 1 1 0 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0
0 1 0 1 1 0 0 1 0 0
0 1 0 0 1 0 1 1 0 0
0 1 0 0 1 0 1 1 0 0
1 1 1 0 1 0 1 0 0 0
0 0 1 0 0 0 1 0 1 1
0 0 1 0 0 0 1 0 1 1
0 1 1 0 1 0 1 0 0 0
0 0 0 0 1 0 1 1 0 0
Coutput
(0,0)->(1,0)->(1,1)->(1,2)->(2,2)
->(3,2)->(3,3)->(4,3)->(5,3)->(6,3)
->(6,4)->(6,5)->(5,5)->(4,5)->(3,5)
->(2,5)->(1,5)->(0,5)->(0,6)->(0,7)
->(0,8)->(0,9)->(1,9)->(2,9)->(3,9)
->(4,9)->(5,9)->(5,8)->(5,7)->(6,7)
->(7,7)->(8,7)->(8,8)->(8,9)->(9,9)
Input
10 10
0 1 1 1 0 0 0 0 0 0
0 0 0 1 0 0 0 1 0 0
0 1 0 1 1 0 0 1 0 0
0 1 0 0 1 0 1 1 0 0
0 1 0 0 1 0 1 1 0 0
1 1 1 0 1 0 1 0 0 0
0 0 1 0 1 0 1 0 1 1
0 0 1 0 1 0 1 0 1 1
0 1 1 0 1 0 1 0 0 0
0 0 0 0 1 0 1 1 0 0
Coutput
NO Path!
三、實驗小結
- 首先,在實現程式碼前,能夠分析題目,設計演算法,攥寫文件,算是自己的一大進步。
- 敢於實現自己的想法,不侷限於老師的提供的方法。比如本實驗中,我沒有新增迷宮的“牆”,只需在探索時注意界限判斷,這節省了空間。
- 不足之處在於,剛開始結合題目考慮棧元素的結構時不夠清晰,導致一時無從設計演算法。
- 本實驗最大的教訓就是,通過原本通過兩個指向結構體的指標判斷這兩個結構體是否相等。其實我想當然的想判斷結構體的值相等,可是函式中返回的是指標,即地址,而且由於不能直接判斷兩個結構體相等,所以並不能通過指標判斷兩個結構體相等,導致這個bug藏得很深。換個思路,從其定義出發,既然不能直接判斷兩個結構體相等,那就判斷結構體裡面的全部元素型別相等。
相關文章
- (C++)資料結構實驗二——迷宮問題C++資料結構
- 【dawn·資料結構】迷宮問題(C++)資料結構C++
- 迷宮問題
- 回溯法求迷宮問題
- POJ3984-迷宮問題
- POJ3984 迷宮問題【BFS】
- 解密迷宮問題:三種高效演算法Java實現,讓你輕鬆穿越未知迷宮解密演算法Java
- 回溯和遞迴實現迷宮問題(C語言)遞迴C語言
- 資料結構實驗1資料結構
- 資料結構實驗(4)資料結構
- 資料結構上機實驗3——圖——外賣成本最優問題資料結構
- 洛谷 p1605 迷宮問題 詳解
- 迷宮問題——最短程式碼,不到70行
- 大資料實驗問題大資料
- 寫資料庫實驗報告資料庫
- 用python深度優先遍歷解迷宮問題Python
- 使用A*演算法解迷宮最短路徑問題演算法
- 資料結構實驗課五-1資料結構
- 資料結構——RMQ(ST表)問題資料結構MQ
- 【資料結構】停車場問題資料結構
- 資料結構括號匹配問題資料結構
- 03.Java資料結構問題Java資料結構
- 江蘇科技大學大二《資料結構》課內實驗報告模板答案資料結構
- c++迷宮問題回溯法遞迴演算法C++遞迴演算法
- 1744 迷宮
- 509迷宮
- 走迷宮
- [SDOI2012] 走迷宮 題解
- 【ybtoj】【BFS】【例題1】走迷宮
- 資料結構實驗三 2024_樹與圖實驗資料結構
- 資料結構實驗三:線性表綜合實驗資料結構
- 資料結構實驗:連結串列的應用資料結構
- 我花了一夜用資料結構給女朋友寫個H5走迷宮遊戲資料結構H5遊戲
- 3090 走迷宮
- 3089 探索迷宮
- 資料結構實驗之連結串列八:Farey序列資料結構
- dfs深度優先搜尋解決迷宮類問題(遍歷)
- 資料結構實驗之佇列一:排隊買飯遇到的函式傳值問題資料結構佇列函式
- 資料結構初階--堆排序+TOPK問題資料結構排序TopK