7.7

混沌武士丞發表於2024-07-07

今天主要完成資料結構第二階段的作業 迷宮問題 學習時間2小時 程式碼時間1小時

#include <stdio.h>
#include <malloc.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

//記錄通道塊在迷宮矩陣當中的橫、縱座標
struct Position {
int x;
int y;
};

//放入棧當中的通道塊元素
struct SElement {
int ord;//記錄步數
Position p;//記錄位置
int di;//記錄下一次測試這一路徑的臨近路徑的位置
};

struct MyStack {
SElement* base;
SElement* top;
int stacksize;
};

//建立一個棧如果建立成功則返回1,否則就返回0
int InitStack(MyStack* s)
{
s->base = (SElement*)malloc(STACK_INIT_SIZE * sizeof(SElement));//為棧分配初始空間
if (!s->base) return 0;
s->top = s->base;//設定為空棧
s->stacksize = STACK_INIT_SIZE;
return 1;
}

//判斷棧是否為空,如果是空的就返回0,否則就返回1
int IsStackEmpty(MyStack* s)
{
if (s->top == s->base) return true;
return false;
}

//獲取棧頂元素,如果棧為空就返回0 否則就返回1
int GetTop(MyStack* s, SElement* e)
{
if (IsStackEmpty(s)) return 0;
e = s->top - 1;
return 1;
}

//獲取棧的長度,並且透過程式返回
int StackLength(MyStack* s)
{
return s->top - s->base;
}

//插入元素e為新的棧頂元素,插入成功則返回1,否則返回0
int Push(MyStack* s, SElement e)
{
if (s->top - s->base >= STACK_INIT_SIZE)
{
s->base = (SElement*)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElement));
if (!s->base) return 0;
s->top = s->base + s->stacksize;
s->stacksize += STACKINCREMENT;
}
*(s->top) = e;
s->top++;
return 1;
}

//彈出棧頂元素賦值給e彈出成功返回1,彈出失敗返回0
int Pop(MyStack* s, SElement* e)
{
if (IsStackEmpty(s)) return 0;
*e = *(s->top - 1);
s->top--;
return 1;
}

//定義牆元素為1 可走路徑為0 已知路徑為curStep 不能夠透過的路徑為-2
#define m 15
#define n 18
int Maze[m][n] = { { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,1,1,1,0,1,0,0,1,0,1,1,1,1,1,0,1 },
{ 1,0,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1 },
{ 1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,1,1 },
{ 1,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,1,1 },
{ 1,1,1,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1 },
{ 1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,1 },
{ 1,1,1,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1 },
{ 1,0,0,1,1,1,1,1,1,0,1,1,0,1,0,0,1,1 },
{ 1,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1 },
{ 1,0,0,1,0,1,0,1,0,0,1,1,0,0,0,1,1,1 },
{ 1,1,0,1,0,1,0,1,1,1,0,0,0,1,1,1,1,1 },
{ 1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1 },
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 } };

//輔助函式考察當前路徑能否透過
bool Pass(Position posi)
{
//只有路徑所在位置的數字為0的是可以走的
if (Maze[posi.x][posi.y] == 0)
{
return true;
}
return false;
}

//按順時針方向從右開始尋找矩陣當中某一個位置的臨近位置
Position NextPosition(Position now, int direction)
{
Position next;
int x = now.x;
int y = now.y;
switch (direction)
{
//右
case 1: {
next.x = x;
next.y = y + 1;
break;
}
//下
case 2: {
next.x = x + 1;
next.y = y;
break;
}
//左
case 3: {
next.x = x;
next.y = y - 1;
break;
}
//上
case 4:
{
next.x = x - 1;
next.y = y;
break;
}
default:break;
}
return next;
}

//改變改點為步驟數
void FootPrint(Position p, int step)
{
Maze[p.x][p.y] = step;
}

//路徑不可走的話就留下-2的標記
void MarkPrint(Position p)
{
Maze[p.x][p.y] = -2;
}

//列印出迷宮矩陣
void Display_migong()
{
for (int i = 0; i<m; i++)
{
for (int j = 0; j<n; j++)
{
if (Maze[i][j]<0)
printf("%d ", Maze[i][j]);
else if (Maze[i][j]<10)
printf("%d ", Maze[i][j]);
else
printf("%d ", Maze[i][j]);
}
printf("\n");
}
}

int main()
{
struct Position path1[m * n]; // 最多能儲存m*n個座標
int pathCount = 0; // 當前已儲存的座標數量
//迷宮程式主體
MyStack path;//記錄路徑的棧
InitStack(&path);//初始化路徑陣列
Position curp;//當前被試位置
Display_migong();
//初始化當前位置為矩陣入口
curp.x = 1;
curp.y = 1;
int curStep = 1;//被探索的步數
do
{
if (Pass(curp))
{
FootPrint(curp, curStep);//可走就在迷宮裡面留下足跡
//建立一個棧元素,儲存可行路徑的相關值,將這個元素儲存到棧當中
SElement e;
e.di = 1;//下一個路塊為這一個路塊的右邊的路塊
e.ord = curStep;
e.p.x = curp.x;
e.p.y = curp.y;
Push(&path, e);//將路徑塊入棧
path1[pathCount++] = curp;
if (curp.x == m - 2 && curp.y == n - 2) break; //如果被壓入的路徑塊到了迷宮的終點就退出迴圈
curp = NextPosition(curp, 1);//找到前一個被試塊東面的路徑塊作為被試塊
curStep++;//被探索的步數加一
}
else//如果當前被試路徑不能夠透過的話
{
if (!IsStackEmpty(&path))
{
SElement e;
Pop(&path, &e);
curStep--;
//將所有的周圍路徑都已經被測試過的路徑從棧中清除
while (e.di == 4 && !IsStackEmpty(&path)) {
MarkPrint(e.p);
Pop(&path, &e);
curStep--;
}
//如果當前棧頂還有未被測試的路徑就測試剩餘的周圍路徑
if (e.di<4)
{
curp = NextPosition(e.p, e.di + 1);
e.di++;
curStep++;
Push(&path, e);
}
}
}
} while (!IsStackEmpty(&path));
printf("\n");
//列印出結果迷宮矩陣
Display_migong();
for (int i = 0; i < pathCount; i++) {
printf("(%d, %d)->", path1[i].x, path1[i].y);
}

return 0;
}

相關文章