(数据结构)栈_迷宫求解(严蔚敏P50) _模仿

一般方法(遍历搜索,寻求最优):

#include"ds.h"

#define MAX_COLUM 10  //迷宫最大列数
#define MAX_ROW 10  //迷宫最大行数
#define MAX_NUM 100  //存储空间初始分配量,估计实际量设定
int NUM[MAX_NUM]; //记录curstep
int NUM_CURSTEP=0; //实际curstep个数

/*用数组表示数据结构书中的迷宫,1表示墙壁,0表示通道*/
int a[MAX_ROW][MAX_COLUM]={
	{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}
	
};

/*结构体表示坐标位置*/
typedef struct Pos{
	int x;
	int y;
}Pos;

Pos Begin={1,1},End={8,8};  //设定迷宫的进口和出口
int curstep=1;

/*最终输出结果*/
void print()
{
	int i,j;
	for(i=0;i<MAX_ROW;i++)
	{
		for(j=0;j<MAX_COLUM;j++)
		printf("%d  ",a[i][j]);  //空格为了方便查看数组
		printf("\n");
	}
}

void Save(int curstep) //记录每次成功搜索所需的步数
{
	NUM[NUM_CURSTEP++]=curstep;
}

int Sort(int NUM[]) //获得最优步数
{
	int i ,j ,temp;
	for(i=0;i<NUM_CURSTEP;i++) //冒泡排列,递增排序
		for(j=i+1;j<NUM_CURSTEP;j++)
		{
			if(NUM[i]>NUM[j])
			{
				temp=NUM[i];
			    NUM[i]=NUM[j];
				NUM[j]=temp;
			}
		}
		return NUM[0];
}

/*路径搜索*/
void Path(Pos position ,int curstep)
{
    int i;
	Pos next_position;
	Pos direction[4]={{0,1},{1,0},{0,-1},{-1,0}}; //搜索方向依次为东南西北

	for(i=0;i<4;i++)
	{
		next_position.x=position.x+direction[i].x;
		next_position.y=position.y+direction[i].y;

		if(a[next_position.x][next_position.y]==0)
		{
			a[next_position.x][next_position.y]=++curstep;
			if(next_position.x!=End.x||next_position.y!=End.y)
				Path(next_position,curstep);
			else
			{
				print();
                printf("\n");
				Save(curstep);
			}
			a[next_position.x][next_position.y]=0;
			curstep--;
		} //if end
	} //for end
}

int main()
{
	int Minstep=0;
	printf("迷宫路径如下:\n");

	a[Begin.x][Begin.y]=1;
    Path(Begin ,1);

	Minstep=Sort(NUM);

	printf("迷宫搜索可行方案总共 %d 组\n",NUM_CURSTEP);
    printf("迷宫搜索最优步数为: %d 步\n",Minstep);

	return 0;
}


利用栈(只寻找一条路径,且很大可能性不是最优路径,不推荐,只是为了熟悉栈):

#include"ds.h"
#define MAX_ROW 7  //迷宫最大行数
#define MAX_COLUMN 7  //迷宫最大列数
#define STACK_INIT_SIZE 10
#define STACK_INCREMENT 2

typedef struct{  //迷宫坐标位置
	int x;
	int y;
}Pos;

typedef struct{  //栈的元素
	int ord;  //路径上的序号
	Pos seat;  //坐标位置
	int di;  //下一步行走的方向
}SElemType;

typedef struct{  //栈
	SElemType *base;
	SElemType *top;
    int stacksize;
}SqStack;

/*用数组表示数据结构书中的迷宫,1表示墙壁,0表示通道*/
int a[MAX_ROW][MAX_COLUMN] = {
	{2, 2, 2, 2, 2, 2, 2}, 
	{2, 0, 0, 0, 0, 0, 2}, 
	{2, 0, 2, 0, 2, 0, 2}, 
	{2, 0, 0, 2, 0, 2, 2}, 
	{2, 2, 0, 2, 0, 2, 2}, 
	{2, 0, 0, 0, 0, 0, 2}, 
	{2, 2, 2, 2, 2, 2, 2}	
}; 

Pos Begin={1,1},End={5,5};  //设定迷宫入口和出口
int curstep=1;  //步数
SqStack S;  //定义一个全局顺序栈

/*构造一个空栈*/
void InitStack(SqStack &S)
{
	S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(!S.base) exit(OVERFLOW);

	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
}

/*判断一个栈是否为空栈,是返回1,不是返回0*/
int StackEmpty(SqStack S)
{
	if(S.base==S.top)
		return 1;
	else 
		return 0;
}

/*插入e为新的栈顶元素*/
void Push(SqStack &S ,SElemType e)
{
	if((S.top-S.base)>=S.stacksize)
	{
		S.base=(SElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType));
	    if(!S.base) exit(OVERFLOW);

	    S.top=S.base+S.stacksize;
        S.stacksize+=STACK_INCREMENT;
	}
	*S.top++=e;
}

/*若栈不为空,则用e删除栈顶元素,并返回OK,否则返回ERROR*/
int Pop(SqStack &S ,SElemType &e)
{
	if(S.top==S.base)
		return ERROR;

	e=*--S.top;
	return OK;
}

/*输出走迷宫的路径*/
void FootPrint()
{
	int i,j;
	for(i=0;i<MAX_ROW;i++)
	{
		for(j=0;j<MAX_COLUMN;j++)
			printf("%d ",a[i][j]);  //空格为了观看方便
		printf("\n");
	}
}

/*求当前位置的下一步*/
void NextStep(Pos &seat ,int di)
{
	Pos direction[4]={{0,1},{1,0},{0,-1},{-1,0}};  //方向依次为东南西北

	seat.x+=direction[di].x;
	seat.y+=direction[di].y;
}

/*搜寻迷宫路径,只能搜索一条路径,且不一定是最优路径*/
/*若能求得一条路径则返回TURE,否则返回FALSE*/
int Path(Pos Begin ,Pos End)
{
	Pos CurPos;
	SElemType e;
	InitStack(S);
	CurPos=Begin;  //将最初位置设定为入口

	do
	{
		if(a[CurPos.x][CurPos.y]==0)  //此时的位置为通路
		{
			a[CurPos.x][CurPos.y]=curstep;
			e.ord=curstep;
			e.seat=CurPos;
			e.di=0;

			Push(S,e);
			curstep++;

			if(CurPos.x==End.x&&CurPos.y==End.y)
				return TRUE;

			NextStep(CurPos,e.di);
		}  //if(a[CurPos.x][CurPos.y]==0) end
		else
		{
			if(!StackEmpty(S))
			{
				Pop(S,e);
				curstep--;
				while(e.di==3&&!StackEmpty(S))
				{
					a[e.seat.x][e.seat.y]=-1;
					Pop(S,e);
					curstep--;
				}  //while(e.di==3&&!StackEmpty(S)) end
				if(e.di<3)
				{
					e.di++;
					Push(S,e);
					curstep++;
					CurPos=e.seat;
					NextStep(CurPos,e.di);
				}  //if(e.di<3)
			}  //if(!StackEmpty(S)) end
		}  //else end
	} while(!StackEmpty(S)); //do end
	return FALSE;
}

int main()
{
	if(Path(Begin ,End))
	{
		printf("路径如下:\n");
        FootPrint();
	}
	else
	{
		printf("此迷宫走不通\n");
	}
	return 0;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值