栈的思想用于求解迷宫问题

来源:互联网 发布:ubuntu 分辨率不能调 编辑:程序博客网 时间:2024/05/21 14:55

迷宫问题是一个经典的问题,当迷宫规模较大时,手工求解是十分困难的,所以用善于进行重复繁琐计算的计算机来求解便十分合适。基本思想和解决“八皇后问题” 的思想一致,都是利用回溯法。从入口开始,探索每一个迷宫中没有被墙挡住的位置,如果该位置可以移动到下一个位置,则标记该位置已被探索过并入栈;如果不能移动到下一位置,则标记为探索失败并回退到上一个位置,如果最终退回了出发点,则说明迷宫无解。下面附上代码:

#include<stdio.h>#include<stdlib.h>#include<time.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define passed 2#define failed 3#define N 2//定义迷宫规模#define NUM (N+2)//定义迷宫总宽度/*迷宫中为1的地方为墙壁,0为可到达的点*/ typedef int status;typedef int elemtype;/*定义位置pos*/ typedef struct pos{    elemtype x;    elemtype y;    elemtype next;//当前位置的下一个位置 }pos;typedef struct sqstack{    pos p[N*N];    int top;}sqstack;int maze[NUM][NUM];//定义迷宫 /*定义栈操作*/ status initstack(sqstack *S){    S->top=-1;}status stacklength(sqstack *S){    return S->top+1;}status push(sqstack *S,pos p){    S->top++;    S->p[S->top]=p;}status pop(sqstack *S){    S->top--;}status gettop(sqstack *S,pos *p){    *p=S->p[S->top];}status emptystack(sqstack *S){    if(S->top==-1)       return TRUE;    else       return FALSE;}/*其他操作*//*********************************/ /*设定位置*/status setpos(pos *p,elemtype x,elemtype y){    p->x=x;    p->y=y; }/*设定下一位置next*/ status setnext(pos *p,elemtype next){    p->next=next;}/*判断是否可以到达下一个位置*/status hasnext(pos *p){    int x=0,y=0;    p->next=0;//p->next用于八个方向的确定     while(p->next<8){        p->next++;        /*这部分代码用来让pos在附近的八个位置移动,以判断是否能到达下一位置*/        switch(p->next){            case 1:                x=p->x+1;                y=p->y+1;                break;            case 2:                x=p->x+1;                y=p->y-1;                break;            case 3:                x=p->x-1;                y=p->y+1;                break;            case 4:                x=p->x-1;                y=p->y-1;                break;            case 5:                x=p->x+1;                y=p->y;                break;            case 6:                x=p->x;                y=p->y+1;                break;            case 7:                x=p->x-1;                y=p->y;                break;            case 8:                x=p->x;                y=p->y-1;                break;        }        /*判断移动之后的位置能否到达*/         if(maze[x][y]==0){             p->x=x;            p->y=y;            p->next=0;            return OK;        }    }    return ERROR;//不能到达,返回ERROR }/*标记探索过且能通过的点*/status markpassedpoint(pos *p){    maze[p->x][p->y]=passed;} /*标记无路可走的点*/status markfailedpoint(pos *p){    maze[p->x][p->y]=failed;}/*判断出口*/status isexit(pos *p){    if(p->x==N&&p->y==N)        return TRUE;    return FALSE;}/*生成迷宫*/status makemaze(void){    int i=0,j=0;    srand(time(0));    for(i=0;i<NUM;i++){        for(j=0;j<NUM;j++){            if(i==0||i==NUM-1||j==0||j==NUM-1)//迷宫四周的墙                 maze[i][j]=1;            else                maze[i][j]=rand()%2;         }    }    maze[1][1]=maze[NUM-2][NUM-2]=0;//定义出入口 }/*打印迷宫*/status printmaze(void){    int i=0,j=0;    for(i=0;i<NUM;i++){        for(j=0;j<NUM;j++){            printf("%d ",maze[i][j]);        }        printf("\n");    }    printf("\n");} /*打印路径*/status printway(sqstack *S){    int i=0;    printf("The avalible way is:\n");    for(i=0;i<S->top;i++)         printf("<%d,%d>->",S->p[i].x,S->p[i].y);    printf("<%d,%d>",S->p[i].x,S->p[i].y);//分开写的目的是让最后一项不出现-> }/*搜索路径*/status searchway(){    sqstack S;    pos p;    initstack(&S);    setpos(&p,1,1);//设置初始位置为(1,1)     setnext(&p,0);//设初始位置下一位置可到达     push(&S,p);    markpassedpoint(&p);    /*栈不空是取最上方点进行判断,判断是否为出口*/     while(!emptystack(&S)){        gettop(&S,&p);        if(isexit(&p)){            printway(&S);            return OK;        }        if(hasnext(&p)){            push(&S,p);            markpassedpoint(&p);        }        else{            pop(&S);            markfailedpoint(&p);        }    }    return ERROR;//最终回到了出发点,返回ERROR表示无解 }status main(void){    sqstack S;    pos p;    initstack(&S);    makemaze();    printf("The Maze is:\n");    printmaze();    if(!searchway()){        printf("\nNo Avalible Ways\n");    }}

2016-04-14更新:
今天在测试自己写的迷宫的过程中,觉得每次用随机数生成的迷宫常常无解,此时就必须要亲自动手才能让程序重新生成迷宫然后重新寻找路径,十分麻烦。于是我对主程序进行了修改,让其只有在生成一个有解的迷宫后再输出答案(我真机智……)代码如下:

int main(void){    stack S;    pos p;    makemaze();    printf("The Maze is:\n");    printmaze();    if(!searchway()){/*如果没找到路*/        while(!searchway()){            makemaze();/*重新生成迷宫*/            printmaze();        }    } }
0 0
原创粉丝点击