自动生成可行迷宫并且用递归和非递归放法求解

本文介绍了一种迷宫求解算法的设计与实现,包括非递归和递归两种方法,同时探讨了如何寻找最短路径及所有可能路径。文中详细展示了迷宫数据结构的构建过程及算法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

迷宫问题求解
一个迷宫可以看成是由 m×n 个房间组成的矩形,迷宫内部的每个房间有 8
个方向,每个方向或者有障碍(如墙)而不能通过,或者无障碍(如有门)而能
通过。入口为左上角房间,出口为右下角房间,问是否有简单路径从入口到出口,
若有则输出一条这样的路径;否则,提示“迷宫无入口到出口的路经”。
要求:

  1. 设计一个迷宫及其障碍的表示方式,并能随机或手动生成迷宫。
  2. 设计并实现一个非递归的算法,输出从入口到出口的一条路径(如存在)。
  3. 设计并实现一个递归的算法,找出从入口到出口的一条路径(如存在)。
  4. 如果有多条路径,设计并实现一个算法找到步数最少的路径(捷径)。
  5. 如果有多条路径,设计并实现一个算法找到所有路径。
  6. 以文件方式保存、并显示原始数据和结果
    需要在d盘根目录下建立lujing.txt和migong.txt文件

#include <iostream>
#include <cstdlib>
#include <ctime>
struct Wall{
    int x;
    int y;
    int direction;
    int count;
    Wall *next;
};
struct Path{
    int length;
    int path[2000][2];
};
struct Path All[2000];
int count[2000];
int M[100][100];
int MA[100][100];
int *Global;
int x ,y ;
int fx[8][2]={{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1},{0,1}};
int path[100][100][2];
//做一个栈
struct node{
    int x;
    int y;
    int v;
    node *next;
};//结点的”型”
typedef node *STACK;
STACK MakeNull()
{ STACK s = NULL;
    s=new node;
    s->next=NULL;
    s->x=0;
    s->v=0;
    s->y=0;
    return s;
}
bool Empty(STACK stk)
{ if (stk->next != NULL)
        return false;
    else
        return true;
}
void Push( int x,int y,int v, STACK stk)
{
    STACK s = NULL;
    s=new node;
    s->x=x;
    s->y=y;
    s->v = v;
    s->next=stk->next;
    stk->next=s;
}
void Pop( STACK stk )
{ STACK s = NULL;
    if (stk->next){/*stk->next!=NULL*/
        s=stk->next;
        stk->next=s->next;
        delete s; /* free(s) */
    } }
STACK Top( STACK stk)
{ if (stk->next)
        return stk->next;
    else
        return NULL; }
void output(STACK K,int counter){
    FILE *fp1 = NULL;
    fp1 = fopen("d:/lujing.txt", "a");
    STACK p = K->next;
    int t = 0;
    int a[5000][2] = {0};
    while (p != NULL){
        a[t][0] = p->x;
        a[t][1] = p->y;
        t++;
        p = p->next;
    }
    All[counter].length = t;
    if (counter == 0){
        fprintf(fp1,"所有路径为:\n");
    }
    for (int i = t-1,j = 0; i >=0; i--,j++) {
        All[counter].path[j][0] = a[i][0];
        All[counter].path[j][1] = a[i][1];
        fprintf(fp1,"%d %d\n",a[i][0],a[i][1]);
        printf("%d %d\n",a[i][0],a[i][1]);
    }
    fprintf(fp1,"###########\n");
    fclose(fp1);
    printf("###########\n");
}
void getShortcut(){
   int flag = 0;
    FILE *fp1 = NULL;
    fp1 = fopen("d:/lujing.txt", "a");
    for (int i = 1; All[i].length!=0; ++i) {
        if (All[i].length < All[flag].length){
            flag = i;
        }
    }
    printf("最短路径的长度为:%d\n",All[flag].length);
    fprintf(fp1,"最短路径的长度为:%d\n",All[flag].length);
    printf("最短路径为:\n");
    fprintf(fp1,"最短路径为:\n");
    for (int j = 0; j < All[flag].length; j++) {
        printf("%d %d\n",All[flag].path[j][0],All[flag].path[j][1]);
        fprintf(fp1,"%d %d\n",All[flag].path[j][0],All[flag].path[j][1]);
    }
}
void setway2(int i,int j,STACK s)
{   int top = 0,g = 0,h = 0,m = x-4,n = y-4,counter = 0,flag = 0;
    MA[1][1] = 1;
    Push(i,j,0,s);
    do { g = i+fx[s->next->v][0] ;
         h = j+fx[s->next->v][1] ;
        if (( g == m) && ( h == n) && (MA[m][n] == 0 )){
            flag = 1;
            //MA[g][h]++;
            //Push(g,h,v,s);
            output(s,counter);
            counter++;
        }
        if ((M[g][h] ==1) && MA[g][h] == 0 && !(g==m&&h==n)){
            MA[g][h] = 1;
            Push( g,h,0,s ) ;
              i = g,j = h;
        }
        else if ( s->next->v < 7 )
            s->next->v++;
        else{
            if (!Empty(s)){
                while (s->next->v == 7){
                Pop(s);
                if (Empty(s)){
                    break;
                }
                MA[i][j]=0;
                i = s->next->x;
                j = s->next->y;}
                if (!Empty(s)){
                    s->next->v++;
                }
//                if (s->next->v<7){
//                    s->next->v++;
//                }
            }
        }
    } while (!Empty(s)) ;
    if (flag == 0) printf("路径不存在");
     }
bool setWay(int i, int j) {
    if(M[x-4][y-4] == 2){
        return true;
    } else if(M[i][j] == 1){
        M[i][j]=2;
        count[0]++;
        path[0][count[0]][0] = i;
        path[0][count[0]][1] = j;
        if(setWay(i,j+1)) {
            return true;
        } else if(setWay(i+1,j+1)){
            return true;
        } else if(setWay(i+1,j)){
            return true;
        } else if(setWay(i+1,j-1)){
            return true;
        }else if (setWay(i,j-1)){
            return true;
        } else if (setWay(i-1,j-1)){
            return true;
        }else if(setWay(i-1,j)){
            return true;
        }else if (setWay(i-1,j+1)){
            return true;
        }else{
            M[i][j]=1;
            path[0][count[0]][0] = 0;
            path[0][count[0]][j] = 0;
            count[0]--;
            return false;
        }
    }else{
        return false;
    }
}
int *CreateMap(int *map,int m,int n){
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            if (i == 0||i == m-1||j == 0||j == n-1){
                map[i*n+j] = 1;
            }
            else if (i % 2 == 0&&j % 2 == 0){
                map[i*n+j] = 1;
            }
            else{
                map[i*n+j] = 0;
            }
        }
    }
    return map;
}
void Print(int *p){
    for (int i = 0; i < x; ++i) {
        for (int j = 0; j < y; ++j) {
            printf("%d",p[i*y+j]);
        }
        printf("\n");
    }
}
void Print1(int *p){
    for (int i = 0; i < x-2; ++i) {
        for (int j = 0; j < y-2; ++j) {
            printf("%d",p[i*y+j]);
        }
        printf("\n");
    }
}
int *Initialize(){
    int *map2;
    map2 = (int *)malloc(sizeof(int)*x*y);
    //用0标记未走过的位置,用1标记走过的位置
    for (int i = 0; i < x; ++i) {
        for (int j = 0; j < y; ++j) {
            if (i == 0||i == x-1||j == 0||j == y-1){
                map2[i*y+j] = 1;
            }
            else if (i % 2 == 0&&j % 2 == 0){
                map2[i*y+j] = 0;
            }
            else{
                map2[i*y+j] = 8;
            }
        }
    }
    return map2;
}
void add(Wall *w,int p,int q,int direction){
    Wall *w1 = w;
    while (w->next != NULL){
        w = w->next;
    }
    Wall *wall1 = new Wall;
    wall1->x = p;
    wall1->y = q;
    wall1->direction = direction;
    wall1->next = NULL;
    w->next = wall1;
    w1->count++;
}
//随机选一个墙
Wall *choose(Wall *K){
    srand(time(NULL));
    Wall *P = K;
    int r;
    r = rand()%K->count + 1;
    for (int i = 0; i < r; i++) {
        P = P->next;
    }
    return P;
}
void remove(Wall *T,Wall *B){
    Wall *N = T;
    while (N->next != B){
        N = N->next;
    }
    N->next = B->next;
    delete B;
    T->count--;
}
void AllWallIn(Wall *w,int f1,int f2){
    add(w,f1,f2+1,1);
    add(w,f1-1,f2+1,2);
    add(w,f1-1,f2,3);
    add(w,f1-1,f2-1,4);
    add(w,f1,f2-1,1);
    add(w,f1+1,f2-1,2);
    add(w,f1+1,f2,3);
    add(w,f1+1,f2+1,4);
}
void CreatM(int *map3,int *mark1){
    Wall *wall = new Wall;
    Wall *J = NULL;
    wall->next = NULL;
    wall->count = 0;
    AllWallIn(wall,2,2);
    while (wall->count != 0){
        J = choose(wall);
        switch (J->direction) {
            case 1:
                if (mark1[J->x*y+J->y+1] == 1&&mark1[J->x*y+J->y-1] == 1){
                    remove(wall,J);
                }
                else if (mark1[J->x*y+J->y+1] == 0){
                    map3[J->x*y+J->y] = 1;
                    mark1[J->x*y+J->y+1] = 1;
                    AllWallIn(wall,J->x,J->y+1);
                }
                else{
                    map3[J->x*y+J->y] = 1;
                    mark1[J->x*y+J->y-1] = 1;
                    AllWallIn(wall,J->x,J->y-1);
                }
                break;
            case 2:
                if (mark1[(J->x-1)*y+J->y+1] == 1&&mark1[(J->x+1)*y+J->y-1] == 1){
                    remove(wall,J);
                }
                else if (mark1[(J->x-1)*y+J->y+1] == 0){
                    map3[J->x*y+J->y] = 1;
                    mark1[(J->x-1)*y+J->y+1] = 1;
                    AllWallIn(wall,J->x-1,J->y+1);
                }
                else{
                    map3[J->x*y+J->y] = 1;
                    mark1[(J->x+1)*y+J->y-1] = 1;
                    AllWallIn(wall,J->x+1,J->y-1);
                }
                break;
            case 3:
                if (mark1[(J->x-1)*y+J->y] == 1&&mark1[(J->x+1)*y+J->y] == 1){
                    remove(wall,J);
                }
                else if (mark1[(J->x-1)*y+J->y] == 0){
                    map3[J->x*y+J->y] = 1;
                    mark1[(J->x-1)*y+J->y] = 1;
                    AllWallIn(wall,J->x-1,J->y);
                }
                else{
                    map3[J->x*y+J->y] = 1;
                    mark1[(J->x+1)*y+J->y] = 1;
                    AllWallIn(wall,J->x+1,J->y);
                }
                break;
            case 4:
                if (mark1[(J->x-1)*y+J->y-1] == 1&&mark1[(J->x+1)*y+J->y+1] == 1){
                    remove(wall,J);
                }
                else if (mark1[(J->x-1)*y+J->y-1] == 0){
                    map3[J->x*y+J->y] = 1;
                    mark1[(J->x-1)*y+J->y-1] = 1;
                    AllWallIn(wall,J->x-1,J->y-1);
                }
                else{
                    map3[J->x*y+J->y] = 1;
                    mark1[(J->x+1)*y+J->y+1] = 1;
                    AllWallIn(wall,J->x+1,J->y+1);
                }
                break;
        }
    }


}
int *CreatMaze(int *map,int *mark){
    int *map1;
    map1 = (int *)malloc(sizeof(int)*(x-2)*(y-2));
    CreatM(map,mark);
//    Print(map);
    for (int i2 = 1,i1 = 0; i2 <= x - 2&&i1 < x-2; ++i2,i1++) {
        for (int j2 = 1,j1 = 0; j2 <= y - 2&&j1 < y-2; ++j2,j1++) {
            if (i2==1&&j2!=0&&j2!=y-1||i2==x-2&&j2!=0&&j2!=y-1||j2==1&&i2!=0&&i2!=x-1||j2==y-2&&i2!=0&&i2!=x-1){
                map[i2*y+j2] = 0;
            }
            map1[i1*y+j1] = map[i2*y+j2];
        }
    }
    return map1;
}
//递归寻路
void copy(int *u){
    for (int i = 0; i < x - 2; ++i) {
        for (int j = 0; j < y - 2; ++j) {
            M[i][j] = u[i*y+j];
        }
    }
}
void PrintM(){
    FILE *fp = NULL;
    fp = fopen("d:/migong.txt", "a");
    fprintf(fp,"随机生成的可行迷宫为:\n");
    for (int i = 0; i < x - 2; ++i) {
        for (int j = 0; j < y-2; ++j) {
            fprintf(fp,"%d",M[i][j]);
            printf("%d",M[i][j]);
        }
        printf("\n");
        fprintf(fp,"\n");
    }
}
void PrintPath(){
    printf("走过的路径为:\n");
    for (int i = 1; i <= count[0]; ++i) {
        printf("%d %d\n",path[0][i][0],path[0][i][1]);
    }
}
int main() {
    setbuf(stdout, NULL);
    printf("请设置迷宫大小:\n");
    scanf("%d,%d",&x,&y);
    if(x % 2 == 0){//保证迷宫的行和列都为奇数
        x++;
    }
    if (y % 2 == 0){
        y++;
    }
    x+=4;
    y+=4;
    int *map;
    int *map2;
    map = (int *)malloc(sizeof(int)*x*y);
    map = CreateMap(map,x,y);
    //printf("#################\n");
    int *mark = Initialize();
    //Initialize();
    //Print(mark);
   // printf("#################\n");
    map2 = CreatMaze(map,mark);
    printf("#################\n");


    //Print1(map2);
    copy(map2);
    //printf("#################\n");
    //MiGong(0, 1, 1);
    printf("生成的迷宫为:\n");
    PrintM();
    STACK n = MakeNull();
    printf("路径为:\n");
    setway2(1,1,n);
    getShortcut();
    //printf("#################\n");
//    if(setWay(1,1)){
//        printf("迷宫的一个路径为:\n");
//        PrintM();
//        printf("路径长度为%d\n",count[0]);
          //PrintPath();
//    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值