• 用栈实现的迷宫问题


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

    头文件:

    #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;
    }


    运行结果:

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

  • 相关阅读:
    AppCompatActivity、ActionBarActivity、FragmentActivity和Activity的区别
    Android-Async-Http
    如何在Android studio中同时打开多个工程?
    Multi-threading Android Apps for Multi-core Processors – Part 1 of 2
    Performance Tips
    容器生态系统
    Docker生态不会重蹈Hadoop的覆辙
    Docker生态会重蹈Hadoop的覆辙吗?
    国外牛人的五个Kubernetes学习建议
    Kubernetes基本概念
  • 原文地址:https://www.cnblogs.com/csudanli/p/4808870.html
Copyright © 2020-2023  润新知