数据结构学习之队列破解迷宫

数据结构学习之队列破解迷宫

0x1 问题描述

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

内容:编写一个程序,求第一条最短路径长度及最短路径。

0x2 解答代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stack>
#define MaxSize 10000+7
#define M 8
#define N 8


using namespace std;
typedef int ElemType;
//typedef ElemType Box;
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}
};
typedef struct
{
    int i,j; //position
    int pre; //前面指针
}Box; //type of block

int next[4][2] ={{-1,0},{0,1},{1,0},{0,-1}};
typedef struct
{
    Box data[MaxSize]; //domain of data
    int front,rear;
}QuType; //type of queue

//Init queue
void InitQueue(QuType *&q)
{
    q = (QuType *)malloc(sizeof(QuType));
    q->front=q->rear=-1;
    return;
}

//Entry queue
bool EnQueue(QuType *&q, Box e)
{
    //if full?
    if(q->rear==MaxSize-1)
        return false;
    q->rear++;
    q->data[q->rear]=e;
    return true;
}

//Leave queue
bool DeQueue(QuType *&q, Box &e)
{
    // if empty
    if(q->front==q->rear)
        return false;
    q->front++;
    e=q->data[q->front];
    return true;
}

// judge empty
bool EmptyQueue(QuType *q)
{
    return(q->rear==q->front);
}
// Destroy queue
void DestroyQueue(QuType *&q)
{
    free(q);
}

void print(QuType *q,int front)
{

    //stack<Box> s;
    int k=front,j,ns=0;
    //cout<< k <<endl;
    /*
    while(k>0)
    {
        printf("k:%d (%d,%d) pre:%d\n",k,q->data[k].i,q->data[k].j,q->data[k].pre);
        k--;
    }
    */
    do
    {
        j=k;
        k=q->data[k].pre;
        //cout<< k <<endl;
        q->data[j].pre=-1;
    }while(k!=0);
    //return;
    printf("一条迷宫路径如下: \n");
    k=0;
    while(k<MaxSize)
    {
        if(q->data[k].pre==-1)
        {
            ns++;
            printf("\t(%d,%d)",q->data[k].i,q->data[k].j);
            if(ns%5==0)
                printf("\n");
        }
        k++;
    }
    printf("\n");

    /*
    int k=front;
    while(q->data[front].pre!=-1)
    {
        //s.push(q->data[front]);
        q->data[front+1].pre=-1;
        q->front=q->data[front].pre;
    }
    //s.push(q->data[1]);
    printf("the least path of map:\n");
    int ns=1;
    while(!s.empty())
    {
        //s.pop();
        ns++;
        //printf("%\t(%d,%d)",e.i,e.j);
        if(ns%5==0)
            printf("\n");
    }
    */
    printf("Length:%d",ns);
}
void myprint(QuType *q,int front)
{
    stack<Box> s;
    while(q->front!=-1)
    {
        s.push(q->data[q->front]);
        q->front=q->data[q->front].pre;
    }
    printf("一条迷宫路径如下:\n");
    int ns=0;
    while(!s.empty())
    {
        Box e=s.top();
        s.pop();
        ns++;
        printf("\t(%d,%d)",e.i,e.j);
        if(ns%5==0)
            printf("\n");
    }
    printf("\nLength:%d\n",ns);
}

bool mgpath(int x,int y,int ex,int ey)
{
    Box e;
    //use a queue
    QuType *q;
    InitQueue(q);
    // enter queue
    e.i=x;
    e.j=y;
    e.pre=-1;
    EnQueue(q,e);
    mg[x][y]=-1;
    while(!EmptyQueue(q))
    {
        DeQueue(q,e);
        //cout<< e.i << e.j<<endl;
        //break;
        //出错重灾区,遍历应该用新的变量
        int il=e.i,jl=e.j;
        if(il==ex && jl==ey)
        {
            //print(q,q->front); //书本例题 感觉太浪费了
            myprint(q,q->front);
            DestroyQueue(q);
            return true;
        }
        for(int i=0;i<4;i++)
        {
            //cout<<next[i][0]<<","<<next[i][1]<<endl;
            int xi=il + next[i][0];
            int yi=jl + next[i][1];
            //cout<< xi << "," <<yi <<endl;
            if(mg[xi][yi]==0)
            {
                //cout<< xi <<","<< yi<<endl;
                e.pre=q->front;
                e.i=xi;
                e.j=yi;
                EnQueue(q,e);
                mg[xi][yi]=-1;
            }
        }
    }
    DestroyQueue(q);
    return false;
}

int main()
{
    int sx=1,sy=1,ex=8,ey=8;// start point and end point
    if(!mgpath(sx,sy,ex,ey))
        printf("can't solve this problem!");
    return 0;
}

0x3 结果

image-20190408180228727

0x4 总结

​ 这个BFS我调试了3.4个小时,原因竟然是在for循环遍历外圈的时候,没有新建变量去接收int new=e.i+next[i][0]导致变量被覆盖,一直没解出结果,归根到底还是自己学的太水了。

猜你喜欢

转载自www.cnblogs.com/xq17dog/p/10672246.html