数据结构之迷宫求解 使用栈

// Maze.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "iostream"

using namespace std;

const int M=10;
const int N=10;
int maze[M][N]=
{
	1,1,1,1,1,1,1,1,1,1,
	1,0,1,0,0,1,1,0,0,1,
	1,0,0,1,0,0,0,0,0,1,
	1,1,0,0,1,0,0,1,0,1,
	1,0,0,1,0,0,0,0,1,1,
	1,1,0,0,0,0,0,0,0,1,
	1,0,0,0,0,0,1,0,1,1,
	1,1,1,1,0,1,0,0,0,1,
	1,0,0,0,0,0,0,0,0,1,
	1,1,1,1,1,1,1,1,1,1
}; // 定义迷宫

int next_xy[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; // 用于计算下一次搜索位置的计算量

typedef struct
{
	int x;
	int y;
}PosType; // 用于记录在迷宫中的位置

typedef struct
{
	int ord;
	PosType seat;
	int di; // 记录方向
}SElemType;  // 栈的元素类型

typedef struct node   
{  
	SElemType data;  
	struct node *link;  
}LinkedNode;  

int Init(LinkedNode *&top);  
int Push(LinkedNode *&top, SElemType e);  
int Pop(LinkedNode *&top,SElemType &e);  
int GetTop(LinkedNode *&top, SElemType &e);  
int StackEmpty(LinkedNode *&top);

int Pass(PosType e);
int FootPrint(PosType e);
PosType NextPos(PosType &e,int di);
int MarkPrint(PosType e);
int MazePath(int MAZE[M][N],PosType start,PosType end,LinkedNode *&stack);

// 定义一个全局的栈
LinkedNode *stack;

int _tmain(int argc, _TCHAR* argv[])
{
	PosType start,end;
	start.x=1;
	start.y=1; // 起点
	end.x=8;
	end.y=8;   // 终点
	// 初始化栈
	Init(stack);
	// 打印当前迷宫
	for (int i=0;i<M;i++)
	{
		for(int j=0;j<N;j++)
		{
			printf("%2d",maze[i][j]);
		}
		printf("\n");
	}
	printf("resolve the maze problem....\n");
	MazePath(maze,start,end,stack); //调用迷宫求解函数
	// 打印当前迷宫
	for (int i=0;i<M;i++)
	{
		for(int j=0;j<N;j++)
		{
			printf("%2d",maze[i][j]);
		}
		printf("\n");
	}
	printf("foot print\n");
	SElemType e;
	while(!StackEmpty(stack))
	{
		Pop(stack,e);
		printf("%d,%d,%d",e.seat.x,e.seat.y,e.ord);
		printf("\n");
	}
	system("pause");
	return 0;
}

// 迷宫路径搜索,对全局栈的引用
int MazePath(int MAZE[M][N],PosType start,PosType end,LinkedNode *&stack)
{
	//LinkedNode *stack;
	//Init(stack); // 初始化栈
	PosType currentPos;
	SElemType e;
	int curstep;

	currentPos=start; // 开始位置
	curstep=1; 
	do 
	{
		if (Pass(currentPos)) // 如果当前结点可通,表示当前结点是第一次访问到
		{
			FootPrint(currentPos); //做访问标记
			e.ord=curstep; // 搜索次数
			e.seat.x=currentPos.x;
			e.seat.y=currentPos.y; // 记录当前可通结点的情况
			e.di=1; // 当前可通结点的访问方向为1,东南西北顺序访问
			Push(stack,e); // 因为当前结点可通,所以将当前结点入栈,进一步判断当前结点的东南西北结点是否可通
						  // 同时,将当前结点入栈,防止下一步不可通的时候从当前结点获得下次可以访问的下个结点
			if ((currentPos.x==end.x)&&(currentPos.y==end.y))
			{
				// 到了出口
				return 1;
			}
			currentPos=NextPos(currentPos,1); // 当前点可通,访问当前点的第一个结点
			curstep++; // 搜索次数加1
		}
		else
		{
			if (!StackEmpty(stack))
			{
				// 当前结点不可通,包括当前结点已经被修改了以后的情况
				Pop(stack,e); // 回到上一个访问结点
				while(e.di==4&&!StackEmpty(stack)) // 当前结点的所有下一步都访问过,且栈不为空,没有路可走,需要返回到上一步
				{
					MarkPrint(e.seat);
					Pop(stack,e);
				}
				if (e.di<4)
				{
					// 还有其他的下一步没有访问到
					e.di++;
					Push(stack,e);
					currentPos=NextPos(e.seat,e.di);
				}
			}
		}
	} while (!StackEmpty(stack)); // 栈不空,则继续寻找下一个可走的结点
	return -1; // 当所有的栈元素出栈以后,栈为空,且没有返回找到的路径,那么说明已经没有其他的路可走,找不到通路
}
// 留下不能通过痕迹
int MarkPrint(PosType e)
{
	int i,j;
	i=e.x;
	j=e.y;
	maze[i][j]=1; //标记不能通过
	return 1;
}

// 计算下一步的位置
PosType NextPos(PosType &e,int di)
{
	e.x=e.x+next_xy[di-1][0];
	e.y=e.y+next_xy[di-1][1];
	return e;
}

// 判断当前点是否可通
int Pass(PosType e)
{
	int i,j;
	i=e.x;
	j=e.y;
	if(maze[i][j]==0)
	{
		// 0 表示当前路径可通
		return 1;
	}
	return 0;
}

int FootPrint(PosType e)
{
	int i,j;
	i=e.x;
	j=e.y;
	maze[i][j]=3; //进行已经访问过标记, 用3表示此点已经访问过
	return 1;
}

int Init(LinkedNode *&top)  
{  
	top=(LinkedNode*)malloc(sizeof(LinkedNode));  
	if (!top)  
	{  
		return -1; // 初始化失败  
	}  
	top->link=NULL;  
	return 1;  
}  

int Push(LinkedNode *&top, SElemType e)  
{  
	node *p=(LinkedNode*)malloc(sizeof(LinkedNode));  
	if (!p)  
	{  
		return -1;  
	}  
	p->data=e;
	p->link=top->link;  
	top->link=p; // 在链表的头部插入新的结点,入栈  
	return 1;  
}  

int Pop(LinkedNode *&top,SElemType &e)  
{  
	if (top->link==NULL)  
	{  
		return -1;  
	}  
	e=top->link->data;  
	node *p=top->link;  
	top->link=top->link->link;  
	free(p);  
	return 1;  
}  

int GetTop(LinkedNode *&top, SElemType &e)  
{  
	if (top->link==NULL)  
	{  
		return -1;  
	}  
	e=top->link->data;
	return 1;  
}

// 判断栈是否为空
int StackEmpty(LinkedNode *&top)
{
	if (top->link==NULL)
	{
		return 1;
	}
	return 0;
}



  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值