用迴圈模擬壓棧來實現迷宮問題
arg.att:這個狀態用來標記我們是否試走過 此處 的四個方位,因為0是牆,1是路,所以我們用2來表示我們試過此處的左邊能不能通行,3用來表示此處的上方是否通行,4表示右邊,5表示下邊。用6來表示出口。假如說試過左邊不能走,我們就將標記改為3,讓他繼續試上邊能不能走。
進入迴圈之前,先將5,2以及初始標記值2壓進棧。
結束條件為,如果目標走到陣列右側,也就是gmaze[ ][n-1]結束,然後跳出整個迴圈。
(如果在這裡結束,我們則只能找到一條通路,我們讓while迴圈來決定是否結束,此時便能找出多個出口)
先看下面的此處座標各個方向能不能走,再看下面這段話:
然後我們檢視棧頂元素,也就是把當前的座標,以及此處的狀態複製到另乙個argnext中
先看左邊能不能走
如果argnext.att<=2說明是剛進來,還沒有試左邊能不能走,因此進入判左語句中
左邊能走我們,將陣列該位置的值改為2,並且列印這個陣列。
將argnext.x -= 1 後,判斷這個點是不是牆、否越界陣列,如果符合條件進入語句
進入語句就說明左邊是能走的通的,然後我們將棧頂的也就是arg的狀態arg.att改為3,說明我們已經走過左邊,並且能走,
改過當前位置的狀態之後,因為此處的左方是能走通的。因此我們需要將左方的座標以及初始狀態也壓入棧內,
左邊能走了,因為下面還有試其他方向的語句,我們讓它每次只走一條路,因此我們需要continue來跳出本次迴圈,假如沒有continue可能會使程式出錯。
試過左邊之後,試上邊能不能走
如果argnext.att<=3說明是已經試過左邊,然後來試上邊。
上邊能走我們,將陣列該位置的值改為3,並且列印這個陣列。
將argnext.y -= 1 後,判斷這個點是不是牆、否越界陣列,如果符合條件進入語句
進入語句就說明上邊是能走的通的,然後我們將棧頂的也就是arg的狀態arg.att改為4,說明我們已經走過上邊,並且能走,
改過當前位置的狀態之後,因為此處的上方是能走通的。因此我們需要將上方的座標以及初始狀態也壓入棧內。然後跳出本次迴圈。
試過上邊之後,試右邊能不能走
如果argnext.att<=4說明是已經試過上邊,然後來試右邊。
右邊能走我們,將陣列該位置的值改為4,並且列印這個陣列。
將argnext.y += 1 後,判斷這個點是不是牆、否越界陣列,如果符合條件進入語句
進入語句就說明右邊是能走的通的,然後我們將棧頂的也就是arg的狀態arg.att改為5,說明我們已經走過右邊,並且能走,
改過當前位置的狀態之後,因為此處的右方是能走通的。因此我們需要將上方的座標以及初始狀態也壓入棧內。然後跳出本次迴圈。
試過右邊之後,試下邊能不能走
如果argnext.att<=5說明是已經試過右邊,然後來試下邊。
右邊能走我們,將陣列該位置的值改為5,並且列印這個陣列。
將argnext.x += 1 後,判斷這個點是不是牆、否越界陣列,如果符合條件進入語句
進入語句就說明下邊是能走的通的,然後我們將棧頂的也就是arg的狀態arg.att改為6,說明我們已經走過下邊,並且能走,
改過當前位置的狀態之後,因為此處的下方是能走通的。因此我們需要將上方的座標以及初始狀態也壓入棧內。然後跳出本次迴圈。
這樣構成乙個迴圈,結束條件為棧為空,結束條件為棧為空時,我們可以尋找迷宮的多個出口。
每次在迴圈中列印陣列時,我門用乙個system(「cls」);來清屏,實現乙個看起來像是能動的迷宮(哈哈哈)
#pragma once
#include
#include
#include
#include
#include
#define max_ 100
#define row 6
#define col 6
//座標結構體
typedef
struct pos
pos;
//座標,當前位置狀態
typedef
struct arg
arg;
//棧typedef
struct stack
stack;
void print();
stack stack;
//迷宮
int gmaze[row][col] = ,,,
,,};//儲存每次路徑的指標陣列
int *gsuccess[row*col];
int gsize = 0;
//儲存最短路徑的指標
int *min = null;
int k = 0;
//定義乙個符號陣列來代替迷宮的1,2,3,4,5,6,
//看起來能直觀一點
static
const
char *symbols = ;
//初始化棧
void init(stack *stack)
//壓棧
void push(stack *stack, arg arg, int att)
//出棧
void pop(stack *stack)
//初始化
void destroy(stack *stack)
//棧大小
int size(stack *stack)
//棧是否為空
int isempty(stack *stack)
//棧頂元素
arg top(stack *stack)
//此位置是否通行
int checkisaccess(int x, int y)
else
}//清屏,並且改變陣列值為當前位置狀態
void setandprint(int x,int y, int att)
//改變棧內,當前座標狀態
void updatetop(stack *stack, int data)
//列印
void print(int (*gmaze)[col])
printf("\n");
}}//主迴圈體
void gomazerecirsion(pos pos)
}argnext = arg;
//左邊能不能走
if (argnext.att <= 2)
}//上邊能不能走
if (argnext.att <= 3)
}//右邊能不能走
if (argnext.att <= 4)
}//下邊能不能走
if (argnext.att <= 5)
}gmaze[arg.pos.x][arg.pos.y] = 1;
pop(&stack);
}printf("沒有通路了\n");
}//主函式體
void test()
; gomazerecirsion(pos);
printf("有%d種方法\n",gsize);
for (i = 0; i < gsize; i++)
printf("最短路徑\n");
print((int(*)[col])min);
//別忘記釋放記憶體
for (i = 0; i < gsize; i++)
free(min);
min = null;
gsuccess[gsize] = null;
system("pause");
}
#include "migong.h"
//主函式
用棧 求迷宮問題(最短路徑和全部路徑)
這是資料結構的作業,便找書邊看網上,然後自己慢慢寫出來的,這裡面主要是回溯法。因為課本上是列印出一條路徑,然後我在想怎樣能將所有的路徑都輸出來,方法 就是當求出一條路徑後,將出口點變成可以走的點 因為之前將其值變成了 1 並且將棧頂元素出棧,還需要得到現在棧頂元素的i,j,di值,將其賦出來。這裡的...
回溯法找迷宮最短路徑
有乙個二維陣列,0表示路,1表示牆,求其中任意兩點的最短路徑 我們先看,怎麼求一條路徑 求兩點路徑是乙個資料結構上的典型的迷宮問題,解決辦法如下 從一點開始出發,向四個方向查詢 上,右,下,左 每走一步,把走過的點的值 1,防止重複行走,並把走過的點壓入堆疊 表示路徑 如果遇到牆 或者已走過的點則不...
迷宮最短路徑問題
問題描述 給定乙個迷宮和乙個起點乙個終點,求起點到終點的最短路徑長度。sample input 說明 5行5列的迷宮,為牆,為路,起點為 0,3 終點為 4,4 sample output 若不可達輸出 1 解答 用bfs的方法,借助乙個佇列實現。1 include2 include3 includ...