數據結構 嚴蔚敏 迷宮求解 代碼

#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

*/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章