用栈实现的迷宫问题

迷宫问题中为了保证任何位置上都能沿原路退回,显然需要用一个先进后出的结果来保存从入口到当前位置的路径。因此,在迷宫通路的算法中应用“栈”也是自然而然的事情

头文件:

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MYOVERFLOW -2
typedef int Status;
typedef struct{
    int x;      //通道块位置的横坐标
    int y;      //通道块位置的纵坐标
    char flag;  //通道块是否可行的标志
}PoseType;
typedef struct{
    int ord;         //通道块在路径上的”序号“
    PoseType seat;   //通道块在迷宫中的”坐标位置“
    int di;          //从此通道块走向下一通道块的”方向“
}SElemtype;          //栈的元素类型
typedef struct{
    SElemtype *base;//在栈构造之前和销毁之后,base的值为NULL
    SElemtype *top;//栈顶!d=====( ̄▽ ̄*)b指针
    int stacksize;//当前已分配的空间储存,以元素为单位
}SqStack;
//-------基本操作的函数原型说明--------
Status visit(SqStack S);//对栈进行遍历
void Create_Stack(SqStack &S);//创建一个栈
Status InitStack(SqStack &S);//构造一个空栈S
Status DestroyStack(SqStack &S);//销毁栈S,S不再存在
Status ClearStack(SqStack &S);//把S置为空栈
Status StackEmpty(SqStack S);//若栈S为空栈,则返回TRUE,否则返回FALSE
int StackLength(SqStack S);//返回S的元素个数,即栈的长度
Status GetTop(SqStack S, SElemtype &e);
//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
Status Push(SqStack &S, SElemtype e);
//插入元素e为新的栈顶元素
Status Pop(SqStack &S, SElemtype &e);
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status StackTraverse(SqStack S, Status(*visit)(SqStack S));
//从栈底到栈顶依次对栈中每个元素调用函数visit()一旦visit()失败,则操作失败
void maze();//一个迷宫,求它从起点到终点的路径

上述操作的实现:

#include "stdafx.h"
Status InitStack(SqStack &S)//构造一个空栈S
{
    S.base = (SElemtype *)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
    if (!S.base)exit(MYOVERFLOW);
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}
Status DestroyStack(SqStack &S)//销毁栈S,S不再存在
{
    for (; S.top != S.base;){
        SElemtype *temp = S.top;
        S.top--;
        delete temp;
    }
    delete S.base;
    S.stacksize = 0;
    return OK;
}
Status ClearStack(SqStack &S)//把S置为空栈
{
    S.top = S.base;
    return OK;
}
Status StackEmpty(SqStack S)//若栈S为空栈,则返回TRUE,否则返回FALSE
{
    if (S.top == S.base)return TRUE;
    else return FALSE;
}
int StackLength(SqStack S)//返回S的元素个数,即栈的长度
{
    int length = 0;
    for (; S.top != S.base; S.top--)length++;
    return length;
}
Status GetTop(SqStack S, SElemtype &e)
//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
{
    if (S.top != S.base){
        e = *(S.top - 1);
        return OK;
    }
    else return ERROR;

}
Status Push(SqStack &S, SElemtype e)
//插入元素e为新的栈顶元素
{
    if (S.top - S.base >= S.stacksize){
        S.base = (SElemtype *)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemtype));
        if (!S.base)exit(MYOVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *(S.top++) = e;
    return OK;
}
Status Pop(SqStack &S, SElemtype &e)
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR
{
    if (S.top != S.base){
        e = *(--S.top);
        return OK;
    }
    else return ERROR;
}
Status visit(SqStack S)//对栈进行遍历1
{
    if (S.base){
        cout << "the data of the Stack is:";
        for (; S.top != S.base;)
        {
            --S.top;
            cout << S.top->di << " " << S.top->ord << " " << S.top->seat.x << ‘,‘ << S.top->seat.y <<S.top->seat.flag<< endl;
        }
        return OK;
    }
    else return ERROR;
}
Status StackTraverse(SqStack S, Status(*visit)(SqStack))
//从栈底到栈顶依次对栈中每个元素调用函数visit()一旦visit()失败,则操作失败
{
    if (visit(S))return OK;
    return ERROR;
}
void Create_Stack(SqStack &S)//创建一个栈
{
    InitStack(S);
    cout << "please input the length of the Stack:";
    int len;
    cin >> len;
    cout << "please input the data of the Stack:";
    for (int i = 1; i <= len; i++){
        SElemtype temp;
        cin >> temp.di>>temp.ord>>temp.seat.x>>temp.seat.y>>temp.seat.flag;
        Push(S, temp);
    }
}
void maze()//一个迷宫,求它从起点到终点的路径
{
    PoseType map[8][8];
    srand((int)time(0));
    for (int i = 0; i <= 7; i++)//构造地图
    {
        cout << "                         ";
        for (int j = 0; j <= 7; j++)
        {
            map[i][j].flag = 2;
            map[i][j].x = i;
            map[i][j].y = j;
            double ran = rand() / (RAND_MAX + 1.0);
            if (ran<= 0.7)map[i][j].flag = 1;//在这个地图中,墙所占的比例为30%
            cout << map[i][j].flag<< " ";
        }
        cout << endl;
    }
    cout << endl << endl << endl << endl;
    map[0][0].flag =0;//起点为地图的左上角
    map[7][7].flag = 1;//终点为地图的右下角
    int t = 1;//是迷宫路径上的第几块通道
    SqStack sq;
    InitStack(sq);//构造一个空的栈
    SElemtype first;
    first.di = 0;
    first.ord = t;
    first.seat = map[0][0];
    Push(sq, first);//将起点放到栈中
    do{
        SElemtype way, nextstep;
        Pop(sq,way);
        switch (way.di)
        {
        case 0:if (way.seat.y < 7 && map[way.seat.x][way.seat.y+1].flag==1){//如果上个通道块的di为0,则地图向右扩展
                   nextstep.di = 0;//新的通道块的di=0;是第++t个通道块,通道块的flag标志为0,说明此通道块被扩展
                   nextstep.ord = ++t;
                   map[way.seat.x][way.seat.y + 1].flag = 0;
                   nextstep.seat = map[way.seat.x][way.seat.y+1];
                   way.di++;//上个通道块的di++,说明右边的通道块已经被扩展
                   Push(sq, way);
                   Push(sq, nextstep);//将上个通道块和新的通道块都压入栈中
                   if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;//如果是终点,则跳出循环
                   break;
        }
               else {                                              //如果向右不能扩展,则di++,并将上个通道块压入栈
                   way.di++; Push(sq, way); break;
               }
        case 1:if(way.seat.x < 7 && map[way.seat.x+1][way.seat.y].flag == 1){//同case 0,这是向下扩展
                   nextstep.di = 0;
                   nextstep.ord = ++t;
                   map[way.seat.x+1][way.seat.y].flag = 0;
                   nextstep.seat = map[way.seat.x+1][way.seat.y];
                   way.di++;
                   Push(sq, way);
                   Push(sq, nextstep);
                   if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;
                   break;
        }
               else {
                   way.di++;
                   Push(sq, way); break;
               }
        case 2:if (way.seat.y >0 && map[way.seat.x ][way.seat.y- 1].flag == 1){//同case 0,这是向左扩展
                   nextstep.di = 0;
                   nextstep.ord = ++t;
                   map[way.seat.x][way.seat.y - 1].flag = 0;
                   nextstep.seat = map[way.seat.x][way.seat.y - 1];
                   way.di++;
                   Push(sq, way);
                   Push(sq, nextstep);
                   if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;
                   break;
        }
               else {
                   way.di++;
                   Push(sq, way); break;
               }
        case 3:if (way.seat.x > 0 && map[way.seat.x-1 ][way.seat.y].flag == 1){//同case 0,这是向上扩展
                   nextstep.di = 0;
                   nextstep.ord = ++t;
                   map[way.seat.x-1][way.seat.y].flag = 0;
                   nextstep.seat = map[way.seat.x-1 ][way.seat.y];
                   way.di++;
                   Push(sq, way);
                   Push(sq, nextstep);
                   if (nextstep.seat.x == 7 && nextstep.seat.y == 7)goto label;
                   break;
        }
               else {
                   way.di++;
                   Push(sq, way); break;
               }
        default:                                         //如果该通道块4个方向上已经被扩展完毕,则将这个通道块的flag设置为3,说明已经被扩展,但此路不通
                map[way.seat.x][way.seat.y].flag = 3;
                t--;
                break;
        }
    } while (!StackEmpty(sq));//当栈为空时,说明没有通路,跳出循环
    label:
    if (StackEmpty(sq)){ cout << "there is no way in the maze!"; exit(-1); }
    for (int i = 0; i <= 7; i++)
    {
        cout << "                         ";
        for (int j = 0; j <= 7; j++)
        {
            cout << map[i][j].flag << " ";
        }
        cout << endl;
    }
}

主函数:

// maze.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    maze();
    return 0;
}

运行结果:

上述实心笑脸表示墙,空心笑脸表示此路可行,最终形成的空白是从起点到终点的通路

时间: 2024-08-10 19:19:11

用栈实现的迷宫问题的相关文章

栈的运用---迷宫

实验2-1 栈与迷宫求解 [实验目的] 1.熟悉C语言的上机环境VC6,掌握C语言程序设计方法与特点. 2.掌握栈的顺序存储结构的定义及C语言实现. 3.掌握栈的顺序存储结构上的各种基本操作. 4.应用栈实现迷宫通路算法. 5.迷宫求解的关键结构定义及C语言实现. [问题说明] 一个迷宫可用n阶方阵表示,1表示能通过,0 表示不能通过.现假设老鼠从左上角[1,1]进入迷宫,编写算法,寻求一条从右下角[n,n] 出去的路径.下图是一个迷宫的示意图: 迷宫示意图 [算法基本思想] 迷宫求解是栈的一个

栈的应用-迷宫解题

总结:这个是网上找的,下面一个是我在他基础上修改的. /* 二. 栈的应用-迷宫解题 */ #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 //坐标类型 typedef struct { int x; in

栈的应用——迷宫

栈和队列是数据结构中重要的部分,通过栈来实现走出迷宫. 1代表不能通行,0代表可以通行,将走的迷宫路线坐标不断地存入栈中,并赋成2,分别判断各个方向,如果是0则前进,1则判断下个方向. 迷宫的地图可以通过新建记事本,将地图输入. 代码实现: struct Pos { int _row;//行 int _col;//列 }; bool CheckIsAccess(int* a,int n,Pos next)//判断是否超出迷宫范围,是否可以前进 { if((next._row>=0)&&

【C++】使用栈Stack解决迷宫问题

我们看下面这个迷宫----方阵(也可以是矩阵): 迷宫入口是坐标(2,0)位置,出口是(9,3).我们假定0代表通路,1代表不通. 现在需要找到哪一条路是通路.我们的思想是借助栈,"回溯法".回溯是什么意思呢???先从起点出发,检查它的上下左右是否是通路(即是否有为数字0处).也就是说为0通了,压栈,将此位置元素变成2,这样做的好处是明确通路路径.然后继续往下走,判断上下左右 .直至我们找到终点(纵坐标在矩阵的最后一行). 我们来看下我针对迷宫问题实现的代码: #include<

栈与回溯:迷宫问题

迷宫问题是栈的典型应用,栈通常也与回溯算法连用. 回溯算法的基本描述是: (1)  选择一个起始点: (2)  如果已达目的地, 则跳转到 (4): 如果没有到达目的地, 则跳转到 (3) ; (3)  求出当前的可选项: a.  若有多个可选项,则通过某种策略选择一个选项,行进到下一个位置,然后跳转到 (2); b.  若行进到某一个位置发现没有选项时,就回退到上一个位置,然后回退到 (2) ; (4) 退出算法. 在回溯算法的实现中,通常要使用栈来保存行进中的位置及选项.本文给出自己写的迷宫

迷宫问题(栈)

"迷宫问题(栈)" "栈"是一种简单的数据结构,它的主要特点就是"先进后出",即就是先压入栈中的数据需要最后出栈.相当于栈是一个杯子,最先放进栈中的东西,只能够最后拿出来.下面对"栈"的特点用图形象的表示出来. 这次所要讨论的是基于栈的迷宫问题,当给定一个迷宫,我们怎样能够找出迷宫中的通道呢?如果迷宫的规模比较大,我们又该如何去实现呢?我们能够明显的知道需要使用一个二维数组用来保存迷宫,但是当迷宫的规模比较大时,或者是当我们想

迷宫问题求解(一)利用栈与递归求解出口

本文适合于对迷宫问题已有初步研究,或阅读代码能力较强的人. 因此,如果你对迷宫问题一无所知,请参考其他更详细的资料. 迷宫问题,是一个对栈(Stack)典型应用的例子之一. 假如,有如下10X10的迷宫(0代表通路,1代表障碍),我们需要用写程序来找出迷宫的出口. 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 0 1 1 0 1 0 0 1 1 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 1 0 0

数据结构应用:利用栈破解迷宫游戏

最近刚开始学数据结构,发现数据结构真是个神奇的东西哈,很多现实中的问题都可以用不同的数据结 构来解决,比如利用和栈中缀表达式编写一个计算机程序,利用栈破解迷宫游戏,今天我就来跟大家分 享一下如何利用栈来破解迷宫游戏. 学过数据结构的人都知道,栈的特点是:后进先出(First In Last Out);也就是说只能在栈的尾部进 行压栈和出栈,而且出栈的时候只能从最后一个数据开始.如下图: 而我们在破解迷宫游戏的时候采用的方法是"回溯",也就是在寻找通路的时候,每找到一个通路,就将这个数据

3-4-迷宫寻路-栈和队列-第3章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第3章  栈和队列 - 迷宫寻路 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.SequenceStack.c        相关测试数据下载