数据结构学习之链栈破解迷宫

数据结构学习之链栈破解迷宫

0x1 问题描述

​ 目的:掌握栈在求解迷宫问题中的应用。

​ 内容:编写一个程序,输出迷宫的所有路径,并求第一条最短路径长度及最短路径。

0x2 解答代码

#include <iostream>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#define MaxSize 100000+7
#define M 8
#define N 8
using namespace std;

typedef int ElemType;
int count=0;
int MinLength=0x3f3f3f3f;
int mg[M+2][N+2]=
{
    {1,1,1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1,0,1},
    {1,0,0,1,0,0,0,1,0,1},{1,0,0,0,0,1,1,0,0,1},
    {1,0,1,1,1,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,1},
    {1,0,1,0,0,0,1,0,0,1},{1,0,1,1,1,0,1,1,0,1},
    {1,1,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1}
};


int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}};

typedef struct
{
    int x;
    int y;
    int di;
}Box;

typedef struct
{
    Box data[MaxSize];
    int top;
}StType;

//存储最短路径
Box path[MaxSize];

//栈的初始化
void Initstack(StType *&s)
{
    s=(StType *)malloc(sizeof(StType));
    s->top=-1;
}

//销毁栈
void Destroystack(StType *s)
{
    free(s);
}
//判断栈是否为空
bool StackEmpty(StType *s)
{
    return(s->top==-1);
}
//进栈
bool Push(StType *&s,Box e)
{
    //判断栈满情况
    if(s->top==MaxSize-1)
        return false;
    s->top++;
    s->data[s->top]=e;
    return true;
}
// 出栈
bool Pop(StType *&s,Box &e)
{
    //判断栈空情况
    if(s->top==-1)
        return false;
    e=s->data[s->top];
    s->top--;
    return true;
}

//取栈顶元素
bool GetTop(StType *&s,Box &e)
{
    if(s->top==-1)
        return false;
    e=s->data[s->top];
    return true;
}

// 返回当前栈的元素个数
int GetLength(StType *s)
{
    return(s->top+1);
}

void Disp(StType *s)
{
    if(s->top==-1)
        cout<< -1 <<endl;
    else
    {
        for(int i=0;i<=s->top;i++)
        {
            printf("\t(%d,%d)",s->data[i].x,s->data[i].y);
            if((i+2)%5==0)
                printf("\n");
        }
        printf("\n");
    }
}
bool mgpath(int xi,int yi,int xe,int ye)
{
    //存放路径
    Box e;
    int i,j,di,i1,j1;
    bool find;
    e.x=xi;e.y=yi;e.di=-1;
    mg[xi][yi]=-1;
    StType *st;
    Initstack(st);
    Push(st,e);
    while(!StackEmpty(st))
    {
        //去头元素
        GetTop(st,e);
        i=e.x,j=e.y,di=e.di;
       // cout<<"i:"<<i<<"j:"<<j<<endl;
        if(i==xe&&j==ye)
        {
            count++;
            int len=GetLength(st);
            printf("第%d条迷宫路径如下: Length:%d\n",count,len);
            Disp(st);
            if(len<MinLength)
            {
                MinLength=len;
                //存储最短路径
                for(int k=0;k<len;k++)
                    path[k]=st->data[k];
            }
            /*
            int k=0;
            while(!StackEmpty(st))
            {
                Pop(st,e);
                path[k++]=e;
            }

            for(int j=0;j<k;j++)
            {
                Push(st,path[j]);
            }
            Pop(st,e);
            mg[e.x][e.y]=0;

            printf("Length:%d\n",k);
            while(k>=1)
            {
                k--;
                printf("\t(%d,%d)",path[k].x,path[k].y);
                if((k+2)%5==0)
                    printf("\n");
            }
            printf("\n");
            //return true;
            */
        }
        find=false;
        while(di<4 && !find)
        {
            di++;
            switch(di)
            {
                case 0:i1=i-1;j1=j;break;
                case 1:i1=i;j1=j+1;break;
                case 2:i1=i+1;j1=j;break;
                case 3:i1=i;j1=j-1;break;
            }
            if(mg[i1][j1]==0) find=true;
        }
        if(find)
        {
            st->data[st->top].di=di;
            e.x=i1;e.y=j1;e.di=-1;
            Push(st,e);
            mg[i1][j1]=-1;
        }else
        {
            Pop(st,e);
            mg[e.x][e.y]=0;
        }
    }
    Destroystack(st);
    return false;
}
//求解主程序
int main()
{
    int sx=1,sy=1;
    int es=8,ey=8;
    mgpath(sx,sy,es,ey);
    if(count!=0)
    {
        cout<< "total num:"<<count<<endl;
        cout<< "最短路径为: Length:"<<MinLength<<endl;
        for(int k=0;k<MinLength;k++)
        {
            printf("\t(%d,%d)",path[k].x,path[k].y);
            if((k+2)%5==0)
                printf("\n");
        }
    }else
    {
        cout<<-1<<endl;
    }
    return 0;
}

0x3 结果

image-20190401230108259

0x4 总结

​ 其实就是dfs的思想,细节处理下,路径保存下就行了。

posted @ 2019-04-01 23:02  xq17  阅读(475)  评论(0编辑  收藏  举报