• 深度优先迷宫求解实例(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("内存分配失败!
    ");
            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("
    ");
        }
    }
    
    
    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("
    
    ");
        if(exist)
            PrintMaze(maze);//输出迷宫的解
        return 0;
    }

    运行截图:

  • 相关阅读:
    用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一:建立MAVEN Web项目
    jvm学习笔记二(减少GC开销的建议)
    jvm学习笔记一(垃圾回收算法)
    【转】 StringUtils中 isNotEmpty 和isNotBlank的区别
    单例模式
    工厂模式
    个人项目作业
    第一次作业-热身!
    第四单元总结
    第三单元总结
  • 原文地址:https://www.cnblogs.com/zhouyifeng/p/7846521.html
Copyright © 2020-2023  润新知