原创 数据结构(C语言)例子连载(2)====迷宫问题收藏

 【问题描述】 
    以一个 m*n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍。设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路。或得出没有通路的结论

【基本要求】
     
【测试数据】

【实现提示】
         使用 穷举法和栈求解

【代码过程】 

1。

//base.h
//------------------- 公用的常量和类型 ----------------------------
#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            //迷宫大小

//~

2。

//stack.h
#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.basereturn 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;
}

//~

3。

//maze.h
//-------------------- 迷宫程序 ----------------------------------
/**************************************************************
    迷宫问题算法:  从入口出发,顺着某一个方向进行探索,若能走通,则继续
前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路,
假如所有可能的通路都探索到而未能达到出口,则所设定的迷宫没有通路.
    说明:可通: 未增走到过的通道快.
  ********************************************************
*/

#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的初值,包括加上边缘一圈的值
    for(int i=1;i<=row;i++){
        
for(int j=1;j<=col;j++){
            maze.arr[i][j] 
= a[i-1][j-1];
        }

    }

    
//加上围墙
    for(int 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;
}

//~

4。

//test.cpp
#include "base.h"        
#include 
"stack.h"                
#include 
"maze.h"            

/**************** 测试 ***********************************/
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("没有找到通路");
}

//~

【界面演示】 



发表于 @ 2006年11月06日 23:58:00|评论(loading...)

新一篇: 数据结构(C语言)例子连载(3)====文学研究助手 | 旧一篇: 数据结构(C语言)例子连载(1)====集合的交、并、差的实现

用户操作
[即时聊天] [发私信] [加为好友]
Raining_CN
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
Raining_CN的公告
这个博客只存放原创性的东西,呵呵!
   * * *
   ◎§◎
      ^
   / | | \
   \ | | /
     /  \
  =====
文章分类
收藏
    友情博客
    雨中的博客
    存档
    软件项目交易
    Csdn Blog version 3.1a
    Copyright © Raining_CN