实验二(必做, 设计性实验,4学时)实验题目:迷宫的求解

实验内容与要求:  迷宫只有两个门,一个叫做入口,另一个叫做出口。把一只老鼠从一个无顶盖的大盒子的入口处赶进迷宫。迷宫中设置很多隔壁,对前进方向形成了多处障碍,在迷宫的唯一出口处放置了一块奶酪,吸引老鼠在迷宫中寻找通路以到达出口。求解迷宫问题,即找出从入口到出口的路径。   【知识要点】        迷宫问题是栈应用的一个典型例子。求解过程可采用回溯法。回溯法是一种不断试探且及时纠正错误的搜索方法。从入口出发,按某一方向向前探索,若能走通(未走过的),即某处可以到达,则到达新点,否则试探下一方向 ; 若所有的方向均没有通路,则沿原路返回前一点,换下一个方向再继续试探,直到所有可能的通路都探索到,或找到一条通路,或无路可走又返回到入口点。在求解过程中,为了保证在到达某一点后不能向前继续行走(无路)时,能正确返回前一点以便继续从下一个方向向前试探,则需要用一个栈保存所能够到达的每一点的下标及从该点前进的方向,栈中保存的就是一条迷宫的通路。        为了确保程序能够终止,调整时,必须保证曾被放弃过的填数序列不被再次试验,即要求按某种有序模型生成填数序列。给解的候选者设定一个被检验的顺序,按这个顺序逐一生成候选者并检验。   【实现提示】        对于迷宫问题,用回溯法的难点就在如何为解空间排序,以确保曾被放弃过的填数序列不被再次试验,在二维迷宫里面,从出发点开始,每个点按四邻域算,按照右、上、左、下的顺序搜索下一落脚点,有路则进,无路即退,前点再从下一个方向搜索,即可构成一有序模型。

实验内容和实验步骤:

1.先根据实验要求设计结构体,结构体为指向四个方向的指针,分别为上下左右,

2.书写创造迷宫的函数creatmaze(),先通过循环创造节点,并且将每一行的第一个节点联接,每一行左右节点连接,再通过第二循环将每一个元素的上下节点连接。

3.书写解决迷宫问题的函数selusion()

先确定入口的位置为头指针,再通过两次循环确定出口指针

再通过循环确定迷宫的解决路经:

当op为1可以走op为0不能走,当没有路径的时候回溯,用next和bef来确定当前路径的下一个节点和前面的节点。

有解决方案以后输出迷宫的解决路径。

代码如下:

#include<stdio.h>

#include <stdlib.h>

#include <string.h>

struct maze {

    int op;

    int remmber;

    int bef;

    int next;

    int x, y;

    maze* up;

    maze* down;

    maze* left;

    maze* right;

};

maze* creatnode(char op,int y,int x)

{

    maze* node = NULL;

    node = (maze*)malloc(sizeof(maze));

    if (node == NULL) {

         printf("malloc fair!\n");

         return NULL;

    }

    node->op = op;

    node->x = x;

    node->y = y;

    node->remmber = 0;

    node->down = NULL;

    node->up = NULL;

    node->left = NULL;

    node->right = NULL;

    return node;

}

maze *creatmaze()

{

    int m, n;

    maze* head = creatnode(0,0,0);

    maze* p = head;

    maze* temp = p;

    maze* q = p;

    int op;

    printf("请输入迷宫的行和列:");

    scanf_s("%d %d", &m, &n);

    int i = 0;

    int j = 0;

    for (i = 0; i < m;i++)

    {

         j = 0;

         scanf_s("%d", &op);

         p->down = creatnode(op,i+1,j+1);

         q = p;

         p = p->down;

         p->up = q;

         temp = p;

         for (j = 1; j < n; j++)

         {

             scanf_s("%d", &op);

             p->right = creatnode(op,i+1,j+1);

             q = p;

             p = p->right;

             p->left = q;

         }

         p = temp;

    }

    p = head->down;

    for (i = 0; i < m - 1; i++)

    {

         q = p;

         p = p->down;

         temp = p;

         for (j = 0; j < n - 1; j++)

         {

             q = q->right;

             p = p->right;

             q->down = p;

             p->up = q;

         }

         p = temp;

    }

    return head->down;

}

void selusion(maze* head)

{

    maze *node = head;

    maze* entry = node;

    maze *exit = NULL;

    maze* p = NULL;

    int right=1;

    int fal=0;

    p = entry;

    p->op = fal;

    p->remmber = 1;

    while (p->down != NULL)

    {

         p = p->down;

    }

    while (p->right != NULL)

    {

         p = p->right;

    }

    exit = p;

    p = entry;

    entry->bef = 1;

    while (1)

    {

         if (p == entry->up)

         {

             printf("该迷宫无解");

             break;

         }

         if(p==exit)

         {

             break;

         }

         if(p->down!=NULL&&p->down->op==right)

         {

             p->next = 2;

             p->down->bef = 1;

             p = p->down;

             p->op = fal;

             p->remmber = 1;

         }

         else

         {

             if (p->up != NULL && p->up->op == right)

             {

                  p->next = 1;

                  p->up->bef = 2;

                  p = p->up;

                  p->op = fal;

                  p->remmber = 1;

             }

             else {

                  if (p->left != NULL&&p->left->op == right)

                  {

                      p->next = 3;

                      p->left->bef = 4;

                      p = p->left;

                      p->op = fal;

                      p->remmber = 1;

                  }

                  else {

                      if (p->right != NULL&&p->right->op == right)

                      {

                          p->next = 4;

                          p->right->bef = 3;

                          p = p->right;

                          p->op = fal;

                          p->remmber = 1;

                      }

                      else {

                          switch (p->bef)

                          {

                          case 1:p = p->up; p->down->bef = 0; p->next = 0; break;

                          case 2:p = p->down; p->up->bef = 0; p->next = 0; break;

                          case 3:p = p->left; p->right->bef = 0; p->next = 0; break;

                          case 4:p = p->right; p->left->bef = 0; p->next = 0; break;

                          }

                      }

                  }

             }

         }

    }

    if (p != entry->up)

    {

         p = entry;

         if(p != exit)

         printf("迷宫出去的路线为(%d,%d)->", p->x, p->y);

         else

         printf("迷宫出去的路线为(%d,%d)", p->x, p->y);

         while (p != exit)

         {

             switch (p->next)

             {

             case 1:p = p->up; printf("(%d,%d)", p->x, p->y); break;

             case 2:p = p->down;  printf("(%d,%d)", p->x, p->y);  break;

             case 3:p = p->left; printf("(%d,%d)", p->x, p->y); break;

             case 4:p = p->right; printf("(%d,%d)", p->x, p->y);  break;

             }

             if (p != exit)

             {

                  printf("->");

             }

             if (p == NULL)

             {

                  break;

             }

         }

    }

}

int main()

{

    maze* creatnode(char op);

    maze* creatmaze();

    maze* head = NULL;

    head = creatmaze();

    selusion(head);

    return 0;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值