《数据结构与算法分析》课程设计——迷宫问题

这篇具有很好参考价值的文章主要介绍了《数据结构与算法分析》课程设计——迷宫问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

中国矿业大学信控学院

 

补一下我之前在博客园发布的内容

 懒得调了,想复制完整代码直接复制最下面的,想复制分布代码去看我博客园链接吧

《数据结构与算法分析》课程设计——迷宫问题 - 刷子zz - 博客园

一、 问题描述

问题中迷宫可用方阵[m,n]表示,0表示能通过,1表示不能通过。若要从从左上角[1,1]进入迷宫,设计算法,寻求一条从右下角 [m,n] 出去的路径。我们用递增的数来代表寻找出口方向与步数,用-2来代表寻找过程中找错的路径。

二、 需求分析

 

需要先创建一个迷宫,在开始后就开始搜寻,当一个点周围有0点(改点并不是以搜寻过的点),那么到这里继续往下搜,如果搜到尽头那么就要倒回去,在搜寻倒回去的周围还有为搜寻过得0点,因此需要一个存储算法,要满足后入先出,那么就是栈,利用栈就可以满足需求。

三、 算法分析

 

1.    首先先定义栈,本问题中,不需要在中间插入与弹出,插入与弹出操作均在栈头,因此我们利用顺序栈。

并且该栈与实验课的栈不同,因为要满足实际需求,所以我们需要定义步数以及改点所在的位置以及临近路径的位置在我们栈中,具体操作如下。

《数据结构与算法分析》课程设计——迷宫问题

 1 //记录通道块在迷宫矩阵当中的横、纵坐标 
 2 struct Position {
 3     int x;
 4     int y;
 5 };
 6 
 7 //放入栈当中的通道块元素 
 8 struct SElement {
 9     int ord;//记录步数
10     Position p;//记录位置 
11     int di;//记录下一次测试这一路径的临近路径的位置 
12 };
13 
14 struct MyStack {
15     SElement* base;
16     SElement* top;
17     int stacksize;
18 };

《数据结构与算法分析》课程设计——迷宫问题

2.    栈的一些列基础操作,例如创建栈,判断栈是否为空,取栈顶元素,获取栈长,入栈,出栈。上述操作类似学校实验中基本操作,这里不在叙述,详见附录中全部代码。

3.    接下来创建迷宫,这里迷宫利用数组来生成,x轴为n,y轴为m

   n为18,m为15。生成方法简单,这里不在叙述,详见附录中全部代码。

4.    接下来定义如何走这个迷宫,考虑我们用0作为通道,1作为墙壁,那么搜寻一个点的上下左右0就是可以通过,1就是不能通过。利用以下循环来完成目标:

步骤1:挪到0处的点并且把刚才位置入栈,让改点改为步数,让步数加一,然后继续搜索其上下左右(除去刚才通过的点)如果有0,继续执行步骤1。

步骤2:如果周围的点无0(除去刚才已经通过的点),让改点改为-2,那么就出栈,把路径调到刚才的那个点,并且把步数减一,然后执行步骤1,搜寻其上下左右(出去刚才走错的点以及入这个点之前的点)。

直至入栈点是终点那么退出循环。

代码如下:

《数据结构与算法分析》课程设计——迷宫问题

 1 do
 2     {
 3         if (Pass(curp))
 4         {
 5             FootPrint(curp, curStep);//可走就在迷宫里面留下足迹 
 6 //创建一个栈元素,存储可行路径的相关值
 7             SElement e;
 8             e.di = 1;// 下一个路块为这一个路块的右边的路块 
 9             e.ord = curStep;
10             e.p.x = curp.x;
11             e.p.y = curp.y;
12             Push(&path, e);//将路径块入栈 
13 if (curp.x == m - 2 && curp.y == n - 2) break; //如果被压入的路径块到了迷宫的终点就退出循环
14             //找到下一个被试块
15 curp = NextPosition(curp, 1);//找到前一个被试块东面的路径块作为被试块
16             curStep++;//被探索的步数加一 
17         }
18         else//如果当前被试路径不能够通过的话 
19         {
20             if (!IsStackEmpty(&path))
21             {
22                 SElement e;
23                 Pop(&path, &e);
24                 curStep--;
25                 //将这一段所有的周围路径都已经被测试过的路径从栈中清除 
26                 while (e.di == 4 && !IsStackEmpty(&path)) {
27                     MarkPrint(e.p);
28                     Pop(&path, &e);
29                     curStep--;
30                 }
31                 //如果当前栈顶还有未被测试的路径就测试剩余的周围路径 
32                 if (e.di<4)
33                 {
34                     curp = NextPosition(e.p, e.di + 1);
35                     e.di++;
36                     curStep++;
37                     Push(&path, e);
38                 }
39             }
40         }
41     } while (!IsStackEmpty(&path));

《数据结构与算法分析》课程设计——迷宫问题

5.    在定义上述代码中如何去搜寻,按照从右到下再到左再到上的方法搜寻。代码如下:

《数据结构与算法分析》课程设计——迷宫问题

 1 //按顺时针方向从右开始寻找矩阵当中某一个位置的临近位置 
 2 Position NextPosition(Position now, int direction)
 3 {
 4     Position next;
 5     int x = now.x;
 6     int y = now.y;
 7     switch (direction)
 8     {
 9         //右 
10         case 1: {
11         next.x = x;
12         next.y = y + 1;
13         break;
14         }
15             //下 
16         case 2: {
17         next.x = x + 1;
18         next.y = y;
19         break;
20         }
21             //左
22         case 3: {
23         next.x = x;
24         next.y = y - 1;
25         break;
26         }
27             //上
28         case 4:{
29         next.x = x - 1;
30         next.y = y;
31         break;
32         }
33         default:break;
34     }
35     return next;
36}

《数据结构与算法分析》课程设计——迷宫问题

6.    定义是否可以通过函数,是就返回ture不是就返回false。代码如下:

《数据结构与算法分析》课程设计——迷宫问题

 1 //辅助函数考察当前路径能否通过 
 2 bool Pass(Position posi)
 3 {
 4     //只有路径所在位置的数字为0的是可以走的 
 5     if (Maze[posi.x][posi.y] == 0)
 6     {
 7         return true;
 8     }
 9     return false;
10 }

《数据结构与算法分析》课程设计——迷宫问题

7.    定义是入栈和出栈时如何修改迷宫数组中的值。代码如下:

《数据结构与算法分析》课程设计——迷宫问题

 1 //改变改点为步骤数 
 2 void FootPrint(Position p, int step)
 3 {
 4     Maze[p.x][p.y] = step;
 5 }
 6 
 7 //路径不可走的话就留下-2的标记 
 8 void MarkPrint(Position p)
 9 {
10     Maze[p.x][p.y] = -2;
11}

《数据结构与算法分析》课程设计——迷宫问题

8.    定义打印迷宫函数,这个就是遍历整个数组,过程简单这里不在叙述,见附录中全部代码。

四、 结论

 编辑ing...

五、 参考文献

[1] 严蔚敏,吴伟民——《数据结构》清华大学出版社2004.2.1

六、 附录

完整代码如下:文章来源地址https://www.toymoban.com/news/detail-498670.html

#include <stdio.h>
#include <malloc.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

//记录通道块在迷宫矩阵当中的横、纵坐标
struct Position {
    int x;
    int y;
};

//放入栈当中的通道块元素
struct SElement {
    int ord;//记录步数
    Position p;//记录位置
    int di;//记录下一次测试这一路径的临近路径的位置
};

struct MyStack {
    SElement* base;
    SElement* top;
    int stacksize;
};

//创建一个栈如果创建成功则返回1,否则就返回0
int InitStack(MyStack* s)
{
    s->base = (SElement*)malloc(STACK_INIT_SIZE * sizeof(SElement));//为栈分配初始空间
    if (!s->base) return 0;
    s->top = s->base;//设定为空栈
    s->stacksize = STACK_INIT_SIZE;
    return 1;
}

//判断栈是否为空,如果是空的就返回0,否则就返回1
int IsStackEmpty(MyStack* s)
{
    if (s->top == s->base) return true;
    return false;
}

//获取栈顶元素,如果栈为空就返回0 否则就返回1
int GetTop(MyStack* s, SElement* e)
{
    if (IsStackEmpty(s)) return 0;
    e = s->top - 1;
    return 1;
}

//获取栈的长度,并且通过程序返回
int StackLength(MyStack* s)
{
    return s->top - s->base;
}

//插入元素e为新的栈顶元素,插入成功则返回1,否则返回0
int  Push(MyStack* s, SElement e)
{
    if (s->top - s->base >= STACK_INIT_SIZE)
    {
        s->base = (SElement*)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElement));
        if (!s->base) return 0;
        s->top = s->base + s->stacksize;
        s->stacksize += STACKINCREMENT;
    }
    *(s->top) = e;
    s->top++;
    return 1;
}

//弹出栈顶元素赋值给e弹出成功返回1,弹出失败返回0
int Pop(MyStack* s, SElement* e)
{
    if (IsStackEmpty(s)) return 0;
    *e = *(s->top - 1);
    s->top--;
    return 1;
}

//定义墙元素为1 可走路径为0 已知路径为curStep 不能够通过的路径为-2
#define m 15
#define n 18
int Maze[m][n] = {  { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
                    { 1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1 },
                    { 1,0,1,1,1,0,1,0,0,1,0,1,1,1,1,1,0,1 },
                    { 1,0,1,1,1,0,1,0,1,1,0,1,0,1,1,0,0,1 },
                    { 1,0,0,0,0,0,1,0,1,1,0,1,0,0,0,0,1,1 },
                    { 1,1,1,1,0,0,1,0,1,1,0,1,1,1,1,0,1,1 },
                    { 1,1,1,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1 },
                    { 1,1,1,0,1,1,1,0,1,1,1,1,0,1,1,0,0,1 },
                    { 1,1,1,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1 },
                    { 1,0,0,1,1,1,1,1,1,0,1,1,0,1,0,0,1,1 },
                    { 1,1,0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1 },
                    { 1,0,0,1,0,1,0,1,0,0,1,1,0,0,0,1,1,1 },
                    { 1,1,0,1,0,1,0,1,1,1,0,0,0,1,1,1,1,1 },
                    { 1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1 },
                    { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 } };

//辅助函数考察当前路径能否通过
bool Pass(Position posi)
{
    //只有路径所在位置的数字为0的是可以走的
    if (Maze[posi.x][posi.y] == 0)
    {
        return true;
    }
    return false;
}

//按顺时针方向从右开始寻找矩阵当中某一个位置的临近位置
Position NextPosition(Position now, int direction)
{
    Position next;
    int x = now.x;
    int y = now.y;
    switch (direction)
    {
        //右
    case 1: {
        next.x = x;
        next.y = y + 1;
        break;
    }
            //下
    case 2: {
        next.x = x + 1;
        next.y = y;
        break;
    }
            //左
    case 3: {
        next.x = x;
        next.y = y - 1;
        break;
    }
            //上
    case 4:
    {
        next.x = x - 1;
        next.y = y;
        break;
    }
    default:break;
    }
    return next;
}

//改变改点为步骤数
void FootPrint(Position p, int step)
{
    Maze[p.x][p.y] = step;
}

//路径不可走的话就留下-2的标记
void MarkPrint(Position p)
{
    Maze[p.x][p.y] = -2;
}

//打印出迷宫矩阵
void Display_migong()
{
    for (int i = 0; i<m; i++)
    {
        for (int j = 0; j<n; j++)
        {
            if (Maze[i][j]<0)
                printf("%d ", Maze[i][j]);
            else if (Maze[i][j]<10)
                printf("%d  ", Maze[i][j]);
            else
                printf("%d ", Maze[i][j]);
        }
        printf("\n");
    }
}

int main()
{

    //迷宫程序主体
    MyStack  path;//记录路径的栈
    InitStack(&path);//初始化路径数组
    Position curp;//当前被试位置
    Display_migong();
    //初始化当前位置为矩阵入口
    curp.x = 1;
    curp.y = 1;
    int curStep = 1;//被探索的步数
    do
    {
        if (Pass(curp))
        {
            FootPrint(curp, curStep);//可走就在迷宫里面留下足迹
//创建一个栈元素,存储可行路径的相关值,将这个元素存储到栈当中
            SElement e;
            e.di = 1;//下一个路块为这一个路块的右边的路块
            e.ord = curStep;
            e.p.x = curp.x;
            e.p.y = curp.y;
            Push(&path, e);//将路径块入栈
if (curp.x == m - 2 && curp.y == n - 2) break; //如果被压入的路径块到了迷宫的终点就退出循环
curp = NextPosition(curp, 1);//找到前一个被试块东面的路径块作为被试块
            curStep++;//被探索的步数加一
        }
        else//如果当前被试路径不能够通过的话
        {
            if (!IsStackEmpty(&path))
            {
                SElement e;
                Pop(&path, &e);
                curStep--;
                //将所有的周围路径都已经被测试过的路径从栈中清除
                while (e.di == 4 && !IsStackEmpty(&path)) {
                    MarkPrint(e.p);
                    Pop(&path, &e);
                    curStep--;
                }
                //如果当前栈顶还有未被测试的路径就测试剩余的周围路径
                if (e.di<4)
                {
                    curp = NextPosition(e.p, e.di + 1);
                    e.di++;
                    curStep++;
                    Push(&path, e);
                }
            }
        }
    } while (!IsStackEmpty(&path));
    printf("\n");
    //打印出结果迷宫矩阵
    Display_migong();
    return 0;
}

到了这里,关于《数据结构与算法分析》课程设计——迷宫问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构课程设计——学生成绩查询与分析系统(简单详细版,含讲解)

    写在前面:欢迎来到「湫歌」的博客。我是秋秋,一名普通的在校大学生。在学习之余,用博客来记录我学习过程中的点点滴滴,也希望我的博客能够更给同样热爱学习热爱技术的你们带来收获!希望大家多多关照,我们一起成长一起进步。也希望大家多多支持我鸭,喜欢我

    2024年02月10日
    浏览(89)
  • 数据结构课程设计题目——链表综合算法设计、带头双向循环链表、插入、显示、删除、修改、排序

      课程设计题目1–链表综合算法设计   一、设计内容   已知简单的人事信息系统中职工记录包含职工编号(no)、职工姓名(name)、部门名称(depname)、职称(title)和工资数(salary)等信息(可以增加其他信息),设计并完成一个简单的人事信息管理系统,要求完成但不

    2024年02月08日
    浏览(64)
  • 燕山大学数据结构与算法课程实践——ISBN号识别系统的设计与开发

            ISBN 号是国际标准书号的简称,它是国际标准化组织于 1972 年公布的一项国际通用的出版物统一编号方法。所有正规出版的普通图书版权页都有 ISBN 号, ISBN 是 international standard of book number 几个英文字母的缩写,即国际标准书号。这个号码印刷在每本图书封底( 或

    2024年03月15日
    浏览(72)
  • 数据结构与算法设计分析—— 数据结构及常用算法

    1、顺序表与链表 线性表是 线性结构 ,是包含n个数据元素的有限序列,通过顺序存储的线性表称为 顺序表 ,它是将线性表中所有元素按照其逻辑顺序,依次存储到指定存储位置开始的一块连续的存储空间里;而通过链式存储的 链表 中,每个结点不仅包含该元素的信息,还

    2024年02月07日
    浏览(62)
  • 【算法与数据结构】--算法基础--算法设计与分析

    一、贪心算法 贪心算法是一种解决优化问题的算法设计方法,其核心思想是在每一步选择当前状态下的最优解,从而希望最终达到全局最优解。下面将介绍贪心算法的原理、实现步骤,并提供C#和Java的实现示例。 1.1 原理: 贪心算法的原理基于局部最优选择,通过在每一步选

    2024年02月07日
    浏览(51)
  • C数据结构与算法——队列 应用(C语言纯享版 迷宫)

    实验任务 (1) 掌握顺序循环队列及其C语言的表示; (2) 掌握入队、出队等基本算法的实现; (3) 掌握顺序循环队列的基本应用(求解迷宫通路)。 实验内容 使用C语言实现顺序循环队列的类型定义与算法函数; 编写main()函数并根据需要修改、补充相关的类型定义与函数,以实

    2024年02月15日
    浏览(56)
  • 数据结构与算法大作业:走迷宫程序(C语言,DFS)(代码以及思路)

    好家伙,写大作业,本篇为代码的思路讲解   问题描述: 以一个 m * n 的长方阵表示迷宫, 0和1分别表示迷宫的通路和障碍。 设计一个程序, 对任意设定的迷宫, 求出一条从入口到出口的通路, 或得出没有通路的结论。 基本要求: (1) 实现一个以链表做存储的栈类型,

    2024年02月03日
    浏览(42)
  • 【Python数据结构与算法】--- 递归算法的应用 ---[乌龟走迷宫] |人工智能|探索扫地机器人工作原理

    🌈个人主页: Aileen_0v0 🔥系列专栏:PYTHON数据结构与算法学习系列专栏 💫\\\"没有罗马,那就自己创造罗马~\\\"  目录 导言  解决过程  1.建立数据结构 2.探索迷宫: 算法思路 递归调用的“基本结束条件” 3.乌龟走迷宫的实现代码: 运行过程: 拓展: 📝全文总结:  乌龟探索迷宫这个问

    2024年02月05日
    浏览(52)
  • 算法分析与设计考前冲刺 (算法基础、数据结构与STL、递归和分治、 动态规划、贪心算法、 回溯算法)

    算法分析与设计考前冲刺 算法基础 算法是一系列解决问题的清晰指令,代表着用系统的方法描述解决问题的策略机制。 程序是算法用某种程序设计语言的具体的 具体实现 算法特征: 有穷性(有限步) 确定性 输入 输出 可行性(有限时间) 算法的复杂性: 时间复杂性 和空间复

    2024年02月02日
    浏览(44)
  • 数据结构课程设计

    编制一个能演示执行集合的交、并和差运算的程序。 要求: 集合元素用小写英文字母,执行各种操作应以对话方式执行。 算法要点:利用单链表表示集合;理解好三种运算的含义 分析 : 输入:输入应该具有判断是否为小写字母的功能,如果不是小写字母,应该舍去,同时

    2024年02月02日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包