数据结构——迷宫问题

  • 数据结构课程设计

  • 迷宫问题求解(栈和队列

任务:可以输入一个任意大小的迷宫数据,用非递归的方法求出一条走出迷宫的路径,并将路径输出;

要求:在上交资料中请写明:存储结构、基本算法(可以使用程序流程图)、源程序、测试数据和结果、算法的时间复杂度、另外可以提出算法的改进方法;

 

  • 分析

该课设意在考察栈和队列的数据结构,我主要说一下代码的设计思路,供诸君参考,也方便以后自己复习。

要说考察掌握栈和队列最好是自己定义一个栈数据结构,我这里偷懒了,直接用的stack头文件,queue没用上。

  • 迷宫使用0(能走)1(不能走)表示
  • 路径存放在栈中
  • 路径节点包含坐标信息x,y和下一个节点相对于该节点的方向信息next(上0右1下2左3 初始值为-1)
  • 输出路径时需要倒换栈中元素顺序(如果使用自己的数据结构可以避免调换,直接倒序输出)

测试数据已给出在代码最后,我自认为代码注释很明白了,有什么问题或者bug欢迎评论留言

  • Code,环境codeblocks17 通过

// @ChenYe 2018/12/27
#include <iostream>
#include <windows.h>
#include <stack>
#include <queue>
#define green SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define white SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN)
#define red SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_INTENSITY)
#define yellow SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define MAXSIZE 100 // 正方形迷宫的最大尺寸
using namespace std;

typedef struct Position
{
    int x,y;    // 横纵坐标
    int next;    // 表示方向,上0右1下2左3 初始值为-1
}Position;

int SearchWay(int x1,int y1,int x2,int y2,int Maze[MAXSIZE][MAXSIZE])
{// 寻找 x1 y1-->x2 y2 的路径
    int x,y,next,Find;
    stack<Position> S;
    Position p;
    p.x=x1;p.y=y1;p.next=-1;
    S.push(p);
    Maze[x1][y1] = -1;  // 走过的路标记为-1
    while(!S.empty())
    {
        x = S.top().x;
        y = S.top().y;
        next = S.top().next;
        if(x==x2&&y==y2)    // 走到了终点
        {
            cout<<"迷宫路径如下:"<<endl;
            stack<Position> SO;
            while(!S.empty())   // 调整栈中元素顺序
            {
                SO.push(S.top());
                S.pop();
            }
            while(!SO.empty())  // 输出
            {
                cout<<"("<<SO.top().x<<","<<SO.top().y<<")-->";
                SO.pop();
            }
            cout<<"end\n";
            return 1;
        }
        // 没走到终点
        Find = 0;
        while(next<4&&Find==0)  // 查找该位置,即当前(x,y)可以走的方向
        {
            next++;
            switch(next)
            {
            case 0:
                x = S.top().x-1;
                y = S.top().y;
                break;
            case 1:
                x = S.top().x;
                y = S.top().y+1;
                break;
            case 2:
                x = S.top().x+1;
                y = S.top().y;
                break;
            case 3:
                x = S.top().x;
                y = S.top().y-1;
                break;
            }
            if(Maze[x][y]==0)   // (x,y)可以走
            {
                Find = 1;
            }
        }

        if(Find == 1)// 走得通
        {// 标记走的方向, 入栈
            S.top().next = next;
            Position temp;
            temp.x = x;
            temp.y = y;
            temp.next = -1;
            S.push(temp);
            Maze[x][y] = -1;    // 访问过标记为-1
        }
        else// 走不通
        {// 退栈
            Maze[S.top().x][S.top().y] = 0; // 迷宫节点回溯为0
            S.pop();
        }
    }
    return 0;   // 无路径
}

void  ManuallyCreate()
{
    int x1,y1,x2,y2;
    int Maze[MAXSIZE][MAXSIZE];
    int n;
    yellow;
    cout<<"注意:迷宫为正方形,3<=尺寸<=100;1表示墙壁,0表示路径。"<<endl;
    white;
    cout<<"输入迷宫尺寸:"<<endl;
    cin>>n;
    cout<<"输入迷宫:"<<endl;
    for(int i=0;i<n;i++)    // 输入
    {
        for(int j=0;j<n;j++)
        {
            cin>>Maze[i][j];
            if(Maze[i][j]!=1&&Maze[i][j]!=0)    // 迷宫合法检验
            {
                red;cout<<"error input!!!"<<endl;white;
                system("pause");
                system("cls");
                return;
            }
        }
    }
    system("cls");

    cout<<"您的迷宫:"<<endl;
    yellow;
    for(int i=0;i<n;i++)    // 输出
    {
        for(int j=0;j<n;j++)
        {
            cout<<Maze[i][j]<<" ";
        }
        cout<<endl;
    }
    white;

    green;cout<<"请输入起点"<<endl;white;
    while(cin>>x1>>y1)
    {
        if(Maze[x1][y1]==1)
        {
            red;cout<<"起点不可行,请重新输入"<<endl;white;
        }
        else
            break;
    }
    green;cout<<"请输入终点"<<endl;white;
    while(cin>>x2>>y2)
    {
        if(Maze[x2][y2]==1||(x2>=n||y2>=n))
        {
            red;cout<<"终点不可行,请重新输入"<<endl;white;
        }
        else
            break;
    }
    int flag = SearchWay(x1,y1,x2,y2,Maze);
    if(flag==0)
        {yellow;cout<<"无可行路径"<<endl;white;}
    system("pause");
    system("cls");

}

void AutomaticallyCreate()
{
    int x1,y1,x2,y2;
    int Maze[MAXSIZE][MAXSIZE]=
{
    {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}
};
    cout<<"迷宫如图所示,1表示墙壁,0表示路径"<<endl;
    yellow;
    for(int i=0;i<10;i++)    // 输出
    {
        for(int j=0;j<10;j++)
        {
            cout<<Maze[i][j]<<" ";
        }
        cout<<endl;
    }
    white;

    green;cout<<"请输入起点"<<endl;white;
    while(cin>>x1>>y1)
    {
        if(Maze[x1][y1]==1)
        {
            red;cout<<"起点不可行,请重新输入"<<endl;white;
        }
        else
            break;
    }
    green;cout<<"请输入终点"<<endl;white;
    while(cin>>x2>>y2)
    {
        if(Maze[x2][y2]==1||(x2>9||y2>9))
        {
            red;cout<<"终点不可行,请重新输入"<<endl;white;
        }
        else
            break;
    }
    int flag = SearchWay(x1,y1,x2,y2,Maze);
    if(flag==0)
        {yellow;cout<<"无可行路径"<<endl;white;}
    system("pause");
    system("cls");
}

void welcome()
{
    green;
    cout<<" ****     ****     **     ******** ********\n/**/**   **/**    ****   //** /**/ \n/**//** ** /**   **//**       **  /**      \n/** //***  /**  **  //**     **   /******* \n/**  //*   /** **********   **    /**  \n/**   /    /**/**//**  **     /**      \n/**        /**/**     /** ********/********\n//         // //      //   \n";
    white;
}

void start()
{
    int choice=0;
    cout<<"请输入迷宫创建方式\n1:手动输入\n2:自动输输入"<<endl;
    cin>>choice;
    if(choice==2)
    {
        system("cls");
        AutomaticallyCreate();
    }
    else if(choice==1)
    {
        system("cls");
        ManuallyCreate();
    }
    else
    {
        red;
        cout<<"error input!!!"<<endl;
        white;
        system("pause");
        system("cls");
    }
}

int main()
{
    while(1)
    {
        welcome();
        start();
    }
    return 0;
}

/*
test data:
1
5
1 1 1 1 1
1 0 0 0 1
1 1 1 0 1
1 0 1 0 1
1 1 1 1 1

1 1
3 3


test data2:
2
1 1
8 8

*/

  • 13
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值