#include "iostream"
#include "malloc.h"
#define TRUE 1;
#define FALSE 0;
#define INIT_STACK_SIZE 20
#define INCREATE_STACK_SIZE 10
typedef int Status;
using namespace std;
//位子座標
struct Position
{
int x;
int y;
};
typedef struct
{
Position pos;
int di;
}SElemType;
typedef struct
{
SElemType * base;
SElemType * top;
int sizeStack;
}MazeStack;
Position BeginPos;
Position EndPos;
int w, h;;
Status InitStack(MazeStack & maze)
{
maze.base = (SElemType *)malloc(sizeof(SElemType) * INIT_STACK_SIZE);
if (maze.base == NULL)
return FALSE;
maze.top = maze.base;
maze.sizeStack = INIT_STACK_SIZE;
return TRUE;
}
Status IsEmpty(MazeStack & maze)
{
if (maze.base == maze.top)
return TRUE;
return FALSE;
}
Status Push(MazeStack & maze, SElemType & ele)
{
if (maze.base - maze.top >= maze.sizeStack)
{
maze.base = (SElemType *)realloc(maze.base, sizeof(SElemType) * (INCREATE_STACK_SIZE + maze.sizeStack));
if (maze.base == NULL)
return FALSE;
maze.top = maze.base + maze.sizeStack;
maze.sizeStack = maze.sizeStack = INCREATE_STACK_SIZE;
}
*maze.top = ele;
maze.top++;
return TRUE;
}
Status Pop(MazeStack & maze, SElemType & ele)
{
if (maze.base == maze.top)
return FALSE;
ele = *(--maze.top);
return TRUE;
}
Status GetTail(MazeStack & maze, SElemType & ele)
{
if (IsEmpty(maze))
return FALSE;
ele = *(maze.top - 1);
return TRUE;
}
//判斷是否是牆
Status Pass(int **a, Position & pos)
{
if (a[pos.x][pos.y] == 0)
return FALSE;
return TRUE;
}
//走過的話,標記爲2
void FootPrint(int ** a, Position & pos)
{
a[pos.x][pos.y] = 2;
}
//設置爲牆
void MarkPrint(int ** a, Position & pos)
{
a[pos.x][pos.y] = 0;
}
//判斷是否走過
SElemType NextPos(int **a, SElemType & ele)
{
switch (ele.di)
{
//向東尋找
case 1:
ele.pos.x++;
if (a[ele.pos.x][ele.pos.y] != 2)
break;
ele.pos.x--;//繼續尋找下去
//向南尋找
case 2:
ele.pos.y++;
if (a[ele.pos.x][ele.pos.y] != 2)
break;//繼續尋找下去
ele.pos.x--;
//向西尋找
case 3:
ele.pos.x--;
if (a[ele.pos.x][ele.pos.y] != 2)
break;
ele.pos.x++;
//最後一個方向,如果走過的話,那麼必然是死路,那麼就將其變成牆
case 4:
ele.pos.y--;
if (a[ele.pos.x][ele.pos.y] == 2)
{
MarkPrint(a, ele.pos);//設爲牆
ele.pos.y++;
}
break;
}
return ele;
}
Status CreateMaze(int ** & a)//如果不傳引用的話,就應該傳*** a
{
int temp;
cout << "請輸入迷宮的長,寬: ";
cin >> w;
cin >> h;
cout << "請輸入迷宮: " << endl;
a = (int **)malloc(sizeof(int *) * h);
if (a == NULL)
{
cout << "創建迷宮失敗!" << endl;
return FALSE;
}
for (int i = 0; i < h; i++)
{
a[i] = (int *)malloc(sizeof(int) * w);
if (a[i] == NULL)
{
cout << "創建迷宮失敗!" << endl;
return FALSE;
}
for (int j = 0; j < w; j++)
{
scanf_s("%d", &temp);
a[i][j] = temp;
}
}
cout << "請輸入入口:" << endl;
cin >> BeginPos.x;
cin >> BeginPos.y;
cout << "請輸入出口:" << endl;
cin >> EndPos.x;
cin >> EndPos.y;
cout << "迷宮創建成功!" << endl;
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
cout << a[i][j] << " ";
cout << endl;
}
}
void DistroyMaze(int ** &a)
{
for (int i = 0; i < h; i++)
delete a[i];
delete a;
}
void MazePath(int ** a, MazeStack & mazeStack)
{
SElemType ele;
ele.pos.x = BeginPos.x;
ele.pos.y = BeginPos.y;
ele.di = 1;
do
{
if (Pass(a, ele.pos)) //如果不是牆
{
ele.di = 1;//如果不是牆的話, 就默認尋找東方
Push(mazeStack, ele); //壓棧
FootPrint(a, ele.pos);//標記走過
if (ele.pos.x == EndPos.x && ele.pos.y == EndPos.y) //如果是出口,不再循環
break;
ele = NextPos(a, ele); //尋找東方是否走過
}
else //如果是牆
{
if (!IsEmpty(mazeStack))
{
Pop(mazeStack, ele);//返回上一步
while (ele.di == 4 && !IsEmpty(mazeStack)) //如果迴路上有好幾個格子的四周都是探索過的那麼,都在迷宮中這些格子置爲牆壁
{
MarkPrint(a, mazeStack.top->pos);
Pop(mazeStack, ele);
}
if (ele.di < 4)
{
ele.di++;
Push(mazeStack, ele); //如果四個方向沒有檢查完,把剛出棧的重新入棧
ele = NextPos(a, ele);
}
}
}
if (ele.di == 4 && IsEmpty(mazeStack))
{
cout << "該迷宮沒有出路!" << endl;
break;
}
} while (true);
}
//輸出倒着了
void ShowMaze(int ** & a, MazeStack & mazeStack)
{
SElemType ele;
while(!IsEmpty(mazeStack))
{
Pop(mazeStack, ele);
cout << "( " << ele.pos.x << "," << ele.pos.y << " ) ";
}
}
int main()
{
MazeStack mazeStack;
InitStack(mazeStack);
int ** a = NULL;
CreateMaze(a);
cout << "---------------------------------" << endl;
MazePath(a, mazeStack);
ShowMaze(a, mazeStack);
DistroyMaze(a);
system("pause");
return 0;
}
/*
測試數據:
1 1
3 3
0 0 0 0 0
0 1 1 1 0
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
*/
數據結構 嚴蔚敏 迷宮求解 代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.