第三章(7).栈的应用举例(3)

同样采用链栈基本操作

typedef struct{
 int x ;
 int y ;
} PosType ;

typedef struct{
 int  ord ;   //通道块在路径上的"序号"
 PosType seat ;   //通道块在迷宫中的"坐标位置"
 int  di ;   //从此通道块向下一通道块的"方向"(1,2,3,4分别表示四个方向)
}ElemType ;

typedef struct SNode    //链栈结点
{
 ElemType data;
 struct SNode *next;
}SNode,*StackNode;

typedef struct
{
 StackNode  top; 
 int stacksize;
}LinkStack;

#define MAXLEN 10
typedef int MazeType[MAXLEN][MAXLEN] ;

#define TRUE 1
#define FALSE 0
#define OK  1
#define ERROR 0

//-------------------迷宫求解------------------------//

int Pass( MazeType maze , PosType curpos )
{
 if( maze[curpos.x][curpos.y] == 1 )
  return OK ;
 return ERROR ;
}

void FootPrint( MazeType maze , PosType curpos , int curstep )
{
 maze[curpos.x][curpos.y] = curstep ; //这里可以不用传递curstep,而随便设定一个特定值
}

PosType NextPos( PosType curpos , int di )
{
 PosType direct[4] = {{0,1},{1,0},{0,-1},{-1,0}}; //分别表示东南西北.依据的中心为{0,0}.
 
 curpos.x +=direct[di].x ;
 curpos.y +=direct[di].y ;
 return curpos ;
}

void MakePrint( MazeType maze , PosType curpos )
{ //留下不能通过的标记
 maze[curpos.x][curpos.y] = -1 ;
}

int MazePath( MazeType maze , PosType start , PosType end )
{ //若迷宫maze中存在从入口start到end的通道,则求得一条存放在栈中(从栈底到栈顶),并返回TRUE,否则返回FALSE
 LinkStack S ;
 PosType curpos ;    //当前位置
 int curstep ;     //当前步数
 ElemType e ;

 InitStack( &S ) ; curpos = start ;curstep = 1 ; //探索第一步
 do{
  if( Pass( maze , curpos ) )     //当前位置可以通过,即是未曾走到过的通道块
  {
   FootPrint( maze , curpos , curstep ); //留下足迹
   e.ord = curstep ; e.seat = curpos ; e.di = 0 ;
   Push( &S , e ) ;      //加入路径
   if( curpos.x==end.x && curpos.y==end.y ) return TRUE ;//到达终点(出口)
   curpos = NextPos( curpos , e.di ) ;  //下一位置是当前位置的东邻
   curstep++ ;        //探索下一步
  }
  else          //当前位置不能通过
  { 
   if( !StackEmpty( S ) )
   {
    Pop( &S , &e ) ;
    curstep-- ;
    while( e.di == 3 && !StackEmpty( S ) ) 
    {
     MakePrint( maze, e.seat ) ; //留下不能通过的标记,并退回一步
     Pop( &S , &e ) ;
     curstep-- ;
    }
    if( e.di < 3 )
    {
     e.di++ ; Push( &S , e ) ;//换下一个方向探索
     curstep++ ;
     curpos = NextPos( e.seat , e.di ) ;//设定当前位置是该新方向上的相邻块
    }
   }
  }//else
 }while( !StackEmpty( S ) ) ;
 return FALSE ;
}

void Print( MazeType maze , int x , int y )
{
 int i , j ;
 for( i = 0 ; i < x ; ++ i )
 {
  for( j = 0 ; j < y ; ++ j )
   printf( "%3d" , maze[i][j] ) ;
  printf( "\n" ) ;
 }
}
void InitMaze( MazeType maze , int x , int y )
{
 int i , j ,row ,col ;

 for( i = 0 ; i < y ; ++ i )   //初始外围行
 {
  maze[ 0 ][ i ] = 0 ;
  maze[ x - 1 ][ i ] = 0 ;
 }
 for( i = 1 ; i < x - 1 ; ++ i )  //初始外围列
 {
  maze[ i ][ 0 ] = 0 ;
  maze[ i ][ y - 1 ] = 0 ;
 }

 for( i = 1 ; i < x - 1 ; ++ i )
  for( j = 1 ; j < y - 1 ; ++ j )
   maze[ i ][ j ] = 1 ;  //定义通道初始值为1.
 
 printf( "输入迷宫内墙单元的个数:" ) ;
 scanf( "%d" , &j ) ;
 fflush(stdin) ;
 printf( "设置迷宫内墙单元的行数以及列数:\n" ) ;
 for( i = 1 ; i <= j ; ++ i )
 {
  scanf( "%d%d" , &row , &col ) ;
  maze[ row ][ col ] = 0 ;
 }
 Print( maze , x , y ) ;
}

//-------------------------------------------------//

int  main( )
{
 PosType start , end ;
 MazeType maze ;
 int x , y ;

 printf( "输入迷宫总行数及总列数:") ;
 scanf( "%d%d" , &x , &y ) ;
 fflush(stdin) ;
    printf( "输入起点行列坐标:") ;
 scanf( "%d%d" , &start.x , &start.y );
 printf( "输入终点行列坐标:") ;
 scanf( "%d%d" , &end.x , &end.y ) ;
 
 InitMaze( maze , x , y ) ;
 if( MazePath( maze , start , end ) )
 {
  printf("此迷宫有一条从出口到入口的路径:\n" );
  Print( maze , x , y ) ;
 }
 else
  printf("此迷宫没有一条从出口到入口的路径!\n") ;

 return 0 ;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值