利用栈数据结构彻底搞定走迷宫案例解析(并非最短路径)

来源:互联网 发布:屏风专卖店淘宝网 编辑:程序博客网 时间:2024/05/29 16:15

**先上迷宫图
这里写图片描述
迷宫数据图我们分0 1 -1 三种可能 0表示可以走白色表示 1表示障碍物 -1表示已经走过
这里写图片描述
方位规则设置:
这里写图片描述
方位也就是我们下面的di的取值为0 1 2 3 这四个方位 表示当前格子可行走的方位
迷宫算法分析:
这里写图片描述
刚开始的时候我们是有迷宫起点也就是(i,j)是当前起点方块
并且还没有找到当前方块的下一个行走方位,我们根据上面的介绍我们知道方位根据顺时针开始标号为0 1 2 3,刚好是个十字架。因此这个时候我们还没有下步方位的话就设置di = -1; 表示还没有下个行走路线。
然后我们把当前方块入栈 也就是i , j -1
这里写图片描述

如果我们找到了当前方块的下个行走方位对应的方块,那么我们就把当前方块的方位给di保存。继续把下个行走方块入栈。

但是路不是一帆风顺的。我们在走的时候也许当前方块附近全部是障碍物也可以啊,那么我们怎么办,如果你进了死胡同咋办,肯定是回到以前的路,并且从没有走的一个出口继续走。那么原先走过的路我们怎么去找,计算机和我们人不同,你不保存以前走过的路,是不会像人一样自动回到过去的路的,我们这个是用了栈数据结构已经把走过的全部方块入栈了,那么我们想回退就把当前走不通的路出栈就可以啊,这样下次出栈就是上次走的方块,这个时候我们就可以以当前方块寻找其他方位有没有通路的情况。当然既然我已经把入栈过的方块出栈了,那么我们是不是要标志一下设置为0呢,这个意思就表示下次也许我用其他路径是可以走的。
记住我假如把当前行走的方块入栈后,我会把当前方块对应的值设置为-1 表示这个方块已经走了,不能在走了。
大家主要学习思路即可

// 利用栈数据结构走迷宫.cpp: 定义控制台应用程序的入口点。#include "stdafx.h"#define  MaxSize 64   //64就够了后面的路径最多把除了墙以外的全部存进来#define  M 8          //地图行#define  N 8          //地图列//全局变量地图数组  我们在外面一层设置为1是墙。  规则0表示可以行走的方块 1是障碍物 //后面我们还会设置地图的值为-1标志我们已经走过,以免重复走进入死循环int MG[M + 2][N + 2] ={    { 1,1,1,1,1,1,1,1,1,1 },    { 1,0,0,1,0,0,1,0,1,1 },    { 1,0,0,0,0,1,0,0,1,1 },    { 1,0,0,0,0,1,0,1,1,1 },    { 1,1,1,1,0,0,0,0,1,1 },    { 1,0,0,0,0,0,1,0,0,1 },    { 1,0,1,1,0,0,0,0,0,1 },    { 1,0,0,0,0,1,1,0,1,1 },    { 1,0,0,1,0,1,0,0,0,1 },    { 1,1,1,1,1,1,1,1,1,1 }};//地宫格子对应的数据类型设计typedef struct{    int i;  //当前方块的行号    int j;  //当前方块的列号    int di; //是下一可行走相邻方位的方位号 可取 0 1 2 3}Box;//迷宫对应的栈数据结构类型设计typedef struct{    Box data[MaxSize]; //可以用来保存我们的行走路径点或者叫可以走的白色方块数据    int top;           //栈顶指针} StType;              //定义顺序栈类型//迷宫数据类型设计  我们假如迷宫的行和列是M = 8,N = 8//我们还会在外面设计一层墙因此加上2侧的围墙数组行的元素个数是M+2//我们规定MG[x][y] = 0表示这个格子可以行走,为1表示是障碍物//MG[x][y] = -1,表示当前格子已经走过//用栈求一条走迷宫的路径算法  起点start(xi,yi)->end(xe,ye)//迷宫数组MG[M+2][N+ 2]bool MGPath(int xi, int yi, int xe, int ye){    //定义需要用到的一些初始化变量    find用来标识我们是不是找到了当前方块走向下个方块:规则0没有找到 1找到    int i, j, di, find;    //定义栈,并初始化栈数据结构    StType st;    st.top = -1; //栈顶指针初始化为-1    //先开始把迷宫起点的方块数据入栈    st.top++;  //入栈前先栈顶指针+1    //开始真正入栈方块    st.data[st.top].i = xi;    st.data[st.top].j = yi;    st.data[st.top].di = -1;    MG[xi][yi] = -1; //是地图的数组数据  表示当前的格子已经走过,下次就不要在走了    //使用循环判断当前入栈的方块是不是就是我们要的终点数据    while (st.top > -1) //栈里有方块才有出栈操作      {        //得到栈顶的方块数据        i = st.data[st.top].i;        j = st.data[st.top].j;        di = st.data[st.top].di;        //比较是不是到了终点        if (i == xe && j == ye) //找到了出口,输出路径        {            printf("(特别提示由于我们的路径是用栈保存,因此输出的路径是从终点到起点)\n迷宫路径如下:\n");            int k = 0;            //用一个死循环来输出我们的迷宫行走方块路径坐标            while (true)            {                if (st.top == -1) break;  //当栈为空的时候就表示没有方块数据了 直接退出即可                k++; //就是用换行用 没有其他作用                //输出方块对应地图中的坐标                printf("\t(%d,%d)", st.data[st.top].i, st.data[st.top].j);                if (k% 5 == 0) //每输出5个方块换一行                {                    printf("\n");                }                st.top--; //由于栈顶方块路径已经输出,那么就出栈当前的一个方块,让指针指向下个方块路径继续循环输出            }                       printf("\n");  //换行            return true; //找到了一条路径就退出循环        }        //开始寻找当前方块的下个可走的方块是什么        find = 0; //初始化为没有找到        //注意di初始是-1的  因为还没有找到下个方位        while (di < 4 && find == 0) //为设么加find必须== 0这个是我们只要找到下个方位就没有必要在找了        {            di++; //当前方块di = -1的  我们这个保证di依次从0到3可以得到当前方块的4个方位的方块            switch (di)            {            case 0:                //注意:由于我们当前的方块是入栈的,因此我们想要得到当前方块的上下左右4个方位的话,                //直接通过栈里的数据来得到   当然我们这里是0方位 表示我们需要得到当前方块的上一个方块的坐标i和j,后面用来测试是不是可以行走                i = st.data[st.top].i - 1;j = st.data[st.top].j;                   break;            case 1:                //得到当前行走方块的右方块的坐标i和j                i = st.data[st.top].i;j = st.data[st.top].j + 1;                break;            case 2:                //得到当前行走方块的下方块的坐标i和j                i = st.data[st.top].i + 1;j = st.data[st.top].j;                break;            case 3:                //得到当前行走方块的左方块的坐标i和j                i = st.data[st.top].i;j = st.data[st.top].j - 1;                break;            default:                break;            }            if (MG[i][j] == 0)   //上面已经得到了i,j,我们这里就直接判断对应坐标在地图中是不是可以行走            {                //说明当前格子是可以行走的                find = 1; //设置标志位            }//找到了下个可走的相邻方块(i,j)        }        if (find == 1) //找到了下个可走的相邻方块(i,j)        {            //进行入栈操作   我们是只要找到可行走方块就会入栈            st.data[st.top].di = di; //设置当前方块的方位di值  注意我们的di是上面得到的            //下面是当前方块可行走的下个方块的入栈操作            st.top++;                //栈指针+1               st.data[st.top].i = i;            st.data[st.top].j = j;            st.data[st.top].di = -1;  //表示下个方位还没找到            MG[i][j] = -1;    //避免重复行走        }        else   //没有路径可以行走        {            MG[st.data[st.top].i][st.data[st.top].j] = 0; //让当前方块下次可以行走            st.top--;    //出栈方块        }    }    return false;  //表示没有可走路径}int main(){    if (!MGPath(1, 1, M, N )) //返回值为false表示没有找到迷宫路径    {        printf("迷宫没有路\n");    }    return 0;}

测试结果如图;
这里写图片描述
注意由于我们是用栈保存的行走方块,栈是先进后出,所以我们输出的路径点是从路径的终点到起点**

原创粉丝点击