<数据结构>栈的应用三:迷宫问题

        求迷宫中从入口到出口的所有路径是一个经典的程序设计问题。由于计算机解迷宫式,通常用的是”穷举法“,即从入口出发,顺某一个方向向前探索,若能走通,则继续往前走;否则沿原路退回,换一个方向再继续探索,直至所有可能的通路都探索为止。为了保证在任何位置上都能沿原路退回,需要一个栈来保存从入口到当前位置的路径。

         迷宫算法的简单思路:若当前位置(”当前位置“指在搜索过程中某一时刻所在图中某个方块的位置)”可通“,则纳入”当前路径“,并继续朝下一个方向探索,如此重复直至到达出口;若当前位置”不可通“,则应顺着”来向“退回”前一通道块“,然后朝着除”来向“外的其他方向继续探索;若该通道块的四周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小节。


与大家分享,共同学习,相互提高,如有疑问或建议,请留言。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值