深度优先迷宫求解实例(C)

//maze.h
#define RIGHT 0
#define DOWN  1
#define LEFT  2
#define UP    3
typedef struct Position{  //位置
    int x; //
    int y; //
}Position;


//顺时针从右开始寻找临近位置,返回该临近位置
Position NextPos(Position now, int dir){
    Position next;
    int x = now.x;
    int y = now.y;

    switch(dir){
        case RIGHT: next.x = x; next.y = y+1; break; //向右走一格
        case DOWN:  next.x = x+1; next.y = y; break; //向下走一格
        case LEFT:  next.x = x; next.y = y-1; break; //向左走一格
        case UP:    next.x = x-1; next.y = y; break; //向上走一格
    }
    return next;
}
//mazeStack.h
#include <stdlib.h>
#include <stdio.h>
#include "maze.h"
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define MAXSIZE 1000
typedef int Status;

//存入栈中的元素
typedef struct Ele{
    Position pos; //当前位置
    int step;     //当前步数
    int dir;      //当前方向
}Ele;

typedef struct{
    int Stacksize;
    Ele* top;
    Ele* base;
}Stack;

//创建一个栈,返回该栈。创建失败返回NULL
Stack* InitStack(void){
    Stack* s = (Stack*)malloc(sizeof(Stack));
    s->base = (Ele*)malloc(STACK_INIT_SIZE*sizeof(Ele));
    if(!s->base){
        //内存分配失败
        printf("内存分配失败!\n");
        return NULL;
    }
    else{
        s->top = s->base;
        s->Stacksize = STACK_INIT_SIZE;
        return s;
    }
}

//判断栈是否为空,是返回1,否返回0
int IsStackEmpty(Stack* s){
    if(s->top == s->base)
        return 1;
    else
        return 0;
}

//获取栈的长度,返回长度
int StackLength(Stack* s){
    return s->top - s->base;
}

//将元素e入栈,成功返回1,失败返回0
int Push(Stack* s, Ele e){
    if(StackLength(s)>=s->Stacksize){
        //栈满,追加存储空间
        s->base = (Ele*)realloc(s->base,(s->Stacksize + STACKINCREMENT)*sizeof(Ele));
        if(!s->base) return 0;
        s->top = s->base + s->Stacksize;
        s->Stacksize += STACKINCREMENT;
    }
    *(s->top)++ = e;
    return 1;
}

//弹出栈顶元素返回给e。成功返回1,失败返回0。
int Pop(Stack* s, Ele* e){
    if(IsStackEmpty(s)) return 0;
    *e = * --s->top;
    return 1;
}

//若栈不空,则用e返回S的栈顶元素,并返回1,否则返回0
int GetTop(Stack* s, Ele* e){

    if(IsStackEmpty(s)){
        return 0;
    }
    *e = *(s->top-1);
    return 1;
}
#include <stdio.h>
#include "mazeStack.h"

//输出迷宫地图
void PrintMaze(int maze[10][10]){
    int i,j;
    for(i=0;i<10;++i){
        for(j=0;j<10;++j){
            switch(maze[i][j]){
                case 0: printf(" "); break; //0表示可走的格子
                case -2: printf("#"); break; //-2表示不可走的障碍物
                case -1:printf(" "); break; //-1表示探索过的格子
                default:printf("*"); break; //1至正无穷表示迷宫解的顺序对应的格子
            }
        }
        printf("\n");
    }
}


int main(void){
    int exist = 1; //迷宫是否有解.1代表有解,0代表无解。
    Stack* path = InitStack();//记录路径
    if(path == NULL) exit(-1);

    Position now; //当前位置
    //初始化位置为入口
    now.x = 1;
    now.y = 1;

    int step=2; //初始步数设为1

    int maze[10][10] = {{-2,-2,-2,-2,-2,-2,-2,-2,-2,-2},    //建立迷宫
                        {-2,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,-2},
                        {-2,0 ,-2,0 ,-2,0 ,-2,0 ,-2,-2},
                        {-2,-2,-2,0 ,-2,-2,-2,0 ,0 ,-2},
                        {-2,0 ,0 ,0 ,-2,0 ,0 ,0 ,-2,-2},
                        {-2,0 ,-2,0 ,0 ,0 ,-2,0 ,-2,-2},
                        {-2,0 ,-2,-2,-2,-2,-2,-2,-2,-2},
                        {-2,0 ,0 ,0 ,0 ,0 ,0 ,0 ,-2,-2},
                        {-2,-2,0 ,-2,0 ,-2,-2,0 ,0 ,-2},
                        {-2,-2,-2,-2,-2,-2,-2,-2,-2,-2},};

    PrintMaze(maze);  //输出迷宫

    while(1){
        if(maze[now.x][now.y]==0){  //若当前格子可走
            maze[now.x][now.y]=step;//走进这个格子
            Ele e;  //初始化一个e
            e.dir = RIGHT;    //初始方向向右
            e.pos.x = now.x;  //e的位置即当前格子
            e.pos.y = now.y;
            e.step = step;    //e记录的步数即为当前步数

            Push(path,e);     //将e入栈(当前格子加入路径)

            if(now.x==8 && now.y==8) break; //若到达终点,则退出循环

            now = NextPos(now,e.dir);  //试探下一个格子

            step++;  //步数+1

        }
        else{  //若当前格子不可走
            if(!IsStackEmpty(path)){
                Ele e;
                Pop(path,&e);  //栈顶元素出栈,赋值给e
                step--;        //步数-1
                if(e.dir<UP){  //如果当前方向不为向上(还没有探索完全部方向)
                    now = NextPos(e.pos,e.dir+1);  //试探另一个方向的下一个格子
                    e.dir++;   //顺时针旋转一次
                    step++;    //步数+1
                    Push(path,e); //将e入栈(当前格子加入路径)
                }
                while(e.dir==UP){ //如果当前方向为向上(说明已探索完全部方向)

                    maze[e.pos.x][e.pos.y] = -1;    //将格子置-1,表示探索完毕
                    Pop(path,&e);     //栈顶元素出栈,赋值给e

                    now.x = e.pos.x;  //当前位置变更为e的位置
                    now.y = e.pos.y;

                    maze[now.x][now.y]=0; //将当前格子设为可探索

                    step--;  //步数-1
                }
            }

            //若起点周围全部探索过说明迷宫无解
            if(maze[1][2]<0 && maze[2][1]<0){
                printf("迷宫无解");
                exist = 0;
                break;
            }
        }

    };

    printf("\n\n");
    if(exist)
        PrintMaze(maze);//输出迷宫的解
    return 0;
}

运行截图:

 

 

posted @ 2017-11-16 21:18  周屹峰  阅读(306)  评论(0编辑  收藏  举报