棧的應用三:迷宮問題

        求迷宮中從入口到出口的所有路徑是一個經典的程序設計問題。由於計算機解迷宮式,通常用的是”窮舉法“,即從入口出發,順某一個方向向前探索,若能走通,則繼續往前走;否則沿原路退回,換一個方向再繼續探索,直至所有可能的通路都探索爲止。爲了保證在任何位置上都能沿原路退回,需要一個棧來保存從入口到當前位置的路徑。

         迷宮算法的簡單思路:若當前位置(”當前位置“指在搜索過程中某一時刻所在圖中某個方塊的位置)”可通“,則納入”當前路徑“,並繼續朝下一個方向探索,如此重複直至到達出口;若當前位置”不可通“,則應順着”來向“退回”前一通道塊“,然後朝着除”來向“外的其他方向繼續探索;若該通道塊的四周4個方向均”不可通“,則應從”當前路徑“上刪除該通道塊。這樣既可得出最後的結果:迷宮是否有路徑可通,如果有路徑是什麼。

結題思路詳見:嚴蔚敏《數據結構》(C語言版)3.2.4小節。

下面給出自己寫的源代碼(僅供參考):

”init.h“:

#ifndef _INIT_H
#define _INIT_H

#include<stdio.h>
#include<stdlib.h>

#define TRUE 1
#define FASLE 0
#define OK 1
#define ERROR -1
#define OVERFLOW -2
typedef int Status;

#endif

”Maze.h“:

#ifndef _MAZE_H
#define _MAZE_H


//定義通道的位置
typedef struct
{
	int x;
	int y;
}Position;

typedef struct 
{
	Position pos;  //通道在迷宮中的座標位置
	int direction;  //從此通道走向下一個通道的“方向”,1、2、3、4分別代表東、南、西、北;
}AccessNode;

//求解出迷宮的一條路徑
Status maze_path(int maze[][10] , Position start, Position end);

#endif

"Maze.c":

#include"init.h"
#include"LinkStack.h"
#include"Maze.h"


//求解出迷宮的一條路徑
Status maze_path(int maze[][10], Position start, Position end)
{
	LinkStack S;
	init_link_stack(S);
	//存儲當前位置
	Position curpos = start;
	do
	{
		//此通道可通,0爲可通,1爲不可通
		if(maze[curpos.x][curpos.y] != 1)
		{
			//走過後,留下足跡
			maze[curpos.x][curpos.y] = 1;

			AccessNode node;
			node.pos = curpos;
			node.direction = 1;
			push(S,node);

			if(curpos.x ==  end.x && curpos.y == end.y)
			{
				printf("找到出口. \n路線如下:");
				display_link_stack(S);
				return OK;
			}
			else
			{
				//設置當前位置的東邊的通道爲當前位置
				++curpos.y;

			}
		}
		else //當前位置不通
		{
			if(S.size != 0)
			{
				AccessNode e;

				pop(S,e);
				while(e.direction == 4 && S.size != 0)
				{
					//標記無法通行
					maze[e.pos.x][e.pos.y] = 1; 
					pop(S,e);
				}

				if(e.direction < 4)
				{
					++e.direction;
					push(S,e);
					switch (e.direction)
					{
					case 1:
						++e.pos.y;

						break;
					case 2:
						++e.pos.x;
						break;
					case 3:
						--e.pos.y;
						break;
					case 4:
						--e.pos.x;
						break;
					}
					curpos.x = e.pos.x;
					curpos.y = e.pos.y;
				}
			}
		}
	}while(S.size != 0);
	printf("此迷宮沒有通路.\n");
	return FASLE;
}

"main.c":

#include"init.h"
#include"LinkStack.h"
#include"Maze.h"

int main()
{
	int maze[10][10]= {
		{1,1,1,1,1,     1,1,1,1,1},
		{1,0,0,1,0,     0,0,1,0,1},
		{1,0,0,1,0,     0,0,1,0,1},
		{1,0,0,0,0,     1,1,0,0,1},
		{1,0,1,1,1,     0,0,0,0,1},

		{1,0,0,0,1,     0,0,0,0,1},
		{1,0,1,0,0,     0,1,0,0,1},
		{1,0,1,1,1,     0,1,1,0,1},
		{1,1,0,0,0,     0,0,0,0,1},
		{1,1,1,1,1,     1,1,1,1,1}
	};
	Position start, end;
	start.x = 1;
	start.y = 1;
	end.x = 8;
	end.y = 8;
	maze_path(maze,  start,  end);
	return 0;
}

運行結果如下:


在這個程序中,用到了在<數據結構>鏈棧的C語言實現中實現的鏈棧。

程序中運行的迷宮圖如下:


上圖來自:嚴蔚敏《數據結構》(C語言版)3.2.4小節。


與大家分享,共同學習,相互提高,如有疑問或建議,請留言。



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