迷宫问题

//------------------- 公用的常量和类型 ----------------------------

#include<stdio.h>

#include <malloc.h>

#include <stdlib.h>

#include <string.h>

//函数结果状态代码

#define    TRUE    1

#define    FALSE    0

#define    OK        1

#define    ERROR    0

#define    INFEASIBLE    -1

#define OVERFLOW    -2    



typedef int    Status;                //函数的返回值

typedef int DirectiveType;        //下一个通道方向



#define RANGE    100            //迷宫大小



#define STACK_INIT_SIZE 100

#define STACKINCREMENT    10



//------------  栈的顺序存储实现  ------------------------------

typedef struct{

	int row;

	int col;

}PosType;



typedef struct{

	int                step;    //当前位置在路径上的"序号"

	PosType            seat;    //当前的坐标位置

	DirectiveType    di;        //往下一个坐标位置的方向

}SElemType;



typedef struct{

	SElemType *base;

	SElemType *top;

	int stacksize;

}SqStack;



//----------------- 栈的基本操作的算法实现 --------------------------------

Status 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;

	return OK;

}



Status GetTop(SqStack s, SElemType &e ){

	if( s.top == s.base) return ERROR;

	e = *(s.top-1);

	return OK;

}



Status Push(SqStack &s, SElemType e){

	if(s.top-s.base >= s.stacksize){    //栈满,追加存储空间

		s.base = (SElemType *)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(SElemType));

		if(!s.base) exit(OVERFLOW);

		s.top = s.base + s.stacksize;

		s.stacksize += STACKINCREMENT;

	}

	*s.top++ = e;

	return OK;

}



Status Pop(SqStack &s, SElemType &e){

	if(s.top==s.base)return ERROR;

	e = * --s.top;

	return OK;

}



int StackEmpty(SqStack s)

{

	return s.base == s.top;

}



Status ClearStack(SqStack &s)

{

	s.top = s.base;

	return OK;

}





//-------------------- 迷宫程序 ----------------------------------

/**//**************************************************************

	迷宫问题算法:  从入口出发,顺着某一个方向进行探索,若能走通,则继续

	前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路,

	假如所有可能的通路都探索到而未能达到出口,则所设定的迷宫没有通路.

	说明:可通: 未增走到过的通道快.

	*********************************************************/

#define ROW 9        //迷宫的行数

#define COL 8       //迷宫的列数



typedef struct{

	int m,n;

	int arr[RANGE][RANGE];

}MazeType;            //迷宫类型



Status InitMaze(MazeType &maze, int a[][COL], int row, int col){

	//按照用户输入的row行和col列的二维数组(0/1)

	//设置迷宫maze的初值,包括加上边缘一圈的值

	int i,j;

	for(i=1;i<=row;i++){

		for(j=1;j<=col;j++){

			maze.arr[i][j] = a[i-1][j-1];

		}

	}

	//加上围墙

	for(j=0;j<=col+1;j++){

		maze.arr[0][j] = maze.arr[row+1][j]=1;

	}

	for(i=0;i<=row+1;i++){

		maze.arr[i][0] = maze.arr[i][col+1]=1;

	}

	maze.m = row, maze.n = col;

	return OK;

}



Status Pass(MazeType maze,PosType curpos){

	//判断当前节点是否通过

	return maze.arr[curpos.row][curpos.col] == 0;

}



Status FootPrint(MazeType &maze,PosType curpos){

	//留下足迹

	maze.arr[curpos.row][curpos.col]='*';

	return OK;

}



Status MarkPrint(MazeType &maze,PosType curpos){

	//留下不能通过的标记

	maze.arr[curpos.row][curpos.col]='@';

	return OK;

}



SElemType CreateSElem(int step, PosType pos, int di){    

	SElemType e;

	e.step = step; e.seat = pos; e.di = di;

	return e;

}



PosType NextPos(PosType curpos, DirectiveType di){

	//返回当前节点的下一节点

	PosType pos = curpos;

	switch(di)

	{

	case 1:        //东

		pos.col++;

		break;

	case 2:        //南

		pos.row++;

		break;

	case 3:        //西

		pos.col--;

		break;

	case 4:        //北

		pos.row--;

		break;

	}

	return pos;

}



Status PosEquare(PosType pos1, PosType pos2){

	//判断两节点是否相等

	return pos1.row==pos2.row && pos1.col==pos2.col ;

}



void PrintMaze(MazeType maze,int row,int col){

	//打印迷宫信息

	for(int i=1;i<=row;i++){

		for(int j=1;j<=col;j++){

			switch(maze.arr[i][j])

			{

			case 0:

				printf("  ");

				break;

			case '*':

				printf("* ");

				break;

			case '@':

				printf("@ ");

				break;

			case 1:

				printf("# ");

				break;

			}            

		}

		printf(" ");

	}

}



Status MazePath(MazeType &maze,PosType start, PosType end){

	//求解迷宫maze中,从入口start到出口end的一条路径

	//若存在,返回TRUE,否则返回FALSE

	SqStack s;SElemType e;

	InitStack(s);

	PosType curpos = start;

	int curstep = 1;                //探索第一部

	do{

		if( Pass(maze,curpos) ){    //如果当前位置可以通过,即是未曾走到的通道块

			FootPrint(maze,curpos);            //留下足迹

			e = CreateSElem(curstep,curpos,1);    //创建元素

			Push(s,e);

			if( PosEquare(curpos,end) )    return TRUE;

			curpos =NextPos(curpos,1);            //获得下一节点:当前位置的东邻

			curstep++;                            //探索下一步

		}else{                        //当前位置不能通过

			if(!StackEmpty(s)){

				Pop(s,e);

				while(e.di==4 && !StackEmpty(s) ){

					MarkPrint(maze,e.seat); Pop(s,e);curstep--;    //留下不能通过的标记,并退回一步

				}

				if(e.di<4){

					e.di++; Push(s,e);            //换一个方向探索

					curpos = NextPos(e.seat,e.di);    //求下一个节点

				}

			}

		}

	}while(!StackEmpty(s));

	return FALSE;

}





/**************** 测试 ***********************************/

void main()

{    

	int a[ROW][COL];

	printf("enter the maze's data: ");

	for(int i=0;i<ROW;i++)

	{

		for(int j=0; j<COL;j++)

		{

			scanf("%d",&a[i][j]);

		}

	}

	PosType start,end;

	start.row = 1;start.col=1;

	end.row = 9; end.col = 8;

	MazeType maze;

	InitMaze(maze,a,ROW,COL);

	Status ok = MazePath(maze,start,end);

	if(ok) PrintMaze(maze,ROW,COL);

	else  printf("没有找到通路");

}



你可能感兴趣的:(问题)