迷宫求解(递归)

原创 2018年04月17日 08:20:11

首先来看一下迷宫简易图
                            这里写图片描述
    我们用 0 来表示该位置是墙, 用 1 来表示该位置是路. 所以, 我们在处理迷宫问题的时候可以将其看成一个二维数组即可, 而对应的每一条路我们可以用坐标的形式将其表示, 所以还需要有一个结构体来描述对应的点的
1. 相关数据结构

typedef struct Maze 
{
    int map[MAX_ROW][MAX_COL];
}Maze;
typedef struct Point
{
    int row;
    int col;
}Point;

2.迷宫初始化
    所谓的初始化迷宫就是将这个二维数组初始化, 我们自己定义一个二维数组, 然后将其每一个值赋值给我们的迷宫地图即可

void MazeInit(Maze* maze)
{
    if(maze == NULL)
    {
        return;
    }
    int Map[MAX_ROW][MAX_COL] = {
        {0, 1, 0, 0, 0, 0},
        {0, 1, 0, 0, 0, 0},
        {0, 1, 0, 0, 0, 0},
        {0, 1, 1, 1, 1, 0},
        {0, 0, 0, 1, 1, 0},
        {0, 0, 0, 1, 0, 0}
    };
    int row = 0;
    int col = 0;
    for(; row < MAX_ROW; row++)
    {
        for(col = 0; col < MAX_COL; col++)
        {
            maze -> map[row][col] = Map[row][col];
        }
    }
}

3.迷宫探索
    迷宫探索即就是从给出的迷宫入口开始, 一直往后探索, 直到找到出口为止. 我们利用函数在递归的过程中会形成栈桢的特性, 依次将我们所探索的为位置进行压栈, 在此过程中, 我们必须得判断当前的点是否合法, 同时必须判断当前的点是否可以落脚, 如果可以落脚, 就现将该位置标记, 然后判断当前位置是否是出口, 如果是出口, 说明迷宫探索完毕, 如果不是出口, 那么我们就得必须找下一个可以落脚的位置, 即我们依次按照顺时针的方向依次遍历当前位置四周的四个点(up, rught, down, left), 只要我们发现有一个点可以落脚, 我们就将当前位置对应的点入栈(调用函数本身), 当四个方向都已经走完了, 那么我们就得往回退, 即就是对应的出栈过程了.具体如下图
                                    这里写图片描述

void _GetPath(Maze* maze, Point cur, Point entry)
{
    if(maze == NULL)
    {
        return;
    }
    if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col > MAX_COL)
    {
        return;
    }
    if(entry.row < 0 || entry.row >= MAX_ROW || entry.col < 0 || entry.col >= MAX_COL)
    {
        return;
    }
    printf("(%d, %d)\n", cur.row, cur.col);
    //判断当前点是否可以落脚
    if(CanStay(maze, cur))
    //如果可以落脚, 就给当前位置标记
    //如果当前点是出口, 则说明找到了一条路按顺时针方向探测四个相邻点, 递归调用函数自身, 
    {
        Mark(maze, cur);
        if(IsExit(maze, cur, entry))
        {
            printf("找到了一条路\n");
            return;
        }
        //递归时更新 cur, (每次递归时, 这里的点是下次要走的点, 无论能不能走交给递归判断)
        Point up = cur;
        up.row -= 1;
        _GetPath(maze, up, entry);

        Point right = cur;
        right.col += 1;
        _GetPath(maze, right, entry);

        Point down = cur;
        down.row += 1;
        _GetPath(maze, down, entry);

        Point left = cur;
        left.col -= 1;
        _GetPath(maze, left, entry);
    }
    else
    {
        return;
    }
}

void GetPath(Maze* maze, Point entry)
{
    if(maze == NULL)
    {
        return;//非法输入
    }
    if(entry.row < 0 || entry.row >= MAX_ROW || entry.col < 0 || entry.col >= MAX_COL)
    {
        return;
    }
    //辅助完成递归
    _GetPath(maze, entry, entry);
    MazePrint(maze);
}

4.判断是否可以落脚
     即先判断迷宫数据结构是否输入合法, 接下来就是判断当前位置是否合法, 如果不合法就退出, 如果当前位置对应的值是 1, 则说明能落脚, 否则就说明不能落脚.

int CanStay(Maze* maze, Point cur)
{
    if(maze == NULL)
    {
        return 0;
    }
    if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col >= MAX_COL)
    {
        return 0;
    }
    if(maze -> map[cur.row][cur.col] == 1)
    {
        return 1;
    }
    return 0;
}

5.判断出口
    如果该位置到达迷宫边界, 并且不等于入口位置, 则说明到达出口

int IsExit(Maze* maze, Point cur, Point entry)
{
    if(maze == NULL)
    {
        return 0;
    }

    if(cur.row == entry.row && cur.col == entry.col)
    {
        return 0;
    }

    if(cur.row == MAX_ROW -1 || cur.row == 0 || cur.col ==MAX_COL -1 || cur.col == 0)
    {
        return 1;
    }
    return 0;
}

6.标记
    将当前位置的值赋值为2

void Mark(Maze* maze, Point cur)
{
    if(maze == NULL)
    {
        return;
    }
    if(cur.row < 0 || cur.row >= MAX_ROW || cur.col < 0 || cur.col >= MAX_COL)
    {
        return;
    }
    maze -> map[cur.row][cur.col] = 2;
}

7.打印迷宫函数

void MazePrint(Maze* maze)
{
    if(maze == NULL)
    {
        return;//非法输入
    }
    int row = 0;
    int col = 0;
    for(; row < MAX_ROW; row++)
    {
        for(col = 0; col < MAX_COL; col++)
        {
            printf("%2d ", maze -> map[row][col]);
        }
        printf("\n");
    }
}

    依次将回溯点打印出来,运行结果如图
                                这里写图片描述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41027326/article/details/79969211

--=== 让你的程序开始说话(在VB中使用文字朗读引擎(TTS)技术)===--

在VB中使用文字朗读引擎(TTS)技术(作者:许锦新 2001年04月10日 13:52)  现今市面上流行的一些英语学习软件,在广告词上经常说自己使用了国际顶尖的全程语音TTS技术,能进行整段英文的...
  • coolstar
  • coolstar
  • 2001-05-04 17:29:00
  • 2338

用栈和递归求解迷宫问题

一、问题概述 小时候,我们都玩过走迷宫的游戏吧。看一下这个图例: 遇到这种问题时,我们第一反应都会先找到迷宫的入口点,然后对上下左右四个方向进行寻迹,  检测当前位置是否是通路,是否可以...
  • xxpresent
  • xxpresent
  • 2016-11-30 21:27:17
  • 2561

【数据结构】递归求解迷宫问题

数据结构 递归求解迷宫问题 参考代码如下: /* 名称:递归求解迷宫问题 编译环境:VC++ 6.0 日期: 2014年4月1日 */ #include #include // 迷宫坐标位置类型...
  • u010870518
  • u010870518
  • 2014-04-01 18:41:14
  • 2617

用递归函数求出迷宫所有解

墙元素值为0,可通过路径为-1,通过路径为足迹。输入格式为X,Y,中间有逗号。依次试探东南西北四个方向 #include using namespace std; struct PosTy...
  • qq_34803572
  • qq_34803572
  • 2016-10-24 23:05:43
  • 770

复杂迷宫问题的递归实现以及最短路径

复杂迷宫就是有多条通路的迷宫,而且要求解最短路的话就要用递归集合栈,用递归探测,寻找所有通路,用栈保存所走过的路径,具体方法为: (1)从当前点为起点探测由它开始能前进的点(这里的探测方向为上,有,...
  • stay_the_course
  • stay_the_course
  • 2017-03-12 19:25:26
  • 783

递归求解迷宫问题

前面已经介绍了迷宫的存储等一些准备工作,这篇博客就只是介绍利用递归思想解决迷宫问题。递归有几个要义:知道在函数的哪里调用自身进行递归,换句话说就是递归的条件是什么,然后递归的出口是什么。 最开始当前...
  • ZLhy_
  • ZLhy_
  • 2013-01-07 14:33:03
  • 3239

关于栈与递归求解迷宫与迷宫最短路径问题

一、栈实现迷宫问题: 问题描述:用一个二维数组模拟迷宫,其中1为墙,0为通路,用栈方法判断迷宫是否有出口,下图为简单模拟的迷宫: 思想: 1.首先给出入口点,如上图入口点坐标为{2,0}; 2.从...
  • L_XRUI
  • L_XRUI
  • 2016-12-03 13:11:24
  • 2299

C语言生成迷宫并用递归算法求解路径

  • 2014年04月25日 14:09
  • 563KB
  • 下载

回溯法解决迷宫问题(方法1---递归)

一、解决思路 1.创建迷宫,用0表示无障碍位置,1表示墙壁,比如迷宫m*p表示m行、p列,用二维数组Maze[m][p].但为了边缘处能够方便处理,在迷宫外层加一层几乎都为1的墙壁,除了进口和入口处设...
  • qq1169091731
  • qq1169091731
  • 2016-04-11 20:38:15
  • 491

迷宫问题递归求解

#include #define M 10//数组大小 #define N 10 int endi=7;//结束点 int endj=3; int v[M][N]={0};//状态位,对应a[...
  • T_W_S
  • T_W_S
  • 2013-05-23 19:47:08
  • 1628
收藏助手
不良信息举报
您举报文章:迷宫求解(递归)
举报原因:
原因补充:

(最多只允许输入30个字)