首页 > 其他分享 >队列迷宫求解最短路径

队列迷宫求解最短路径

时间:2024-05-29 22:01:56浏览次数:26  
标签:pre Box 课程设计 qu 队列 迷宫 最短 int

目录

课程设计目的

课程设计内容和要求

问题描述

      2.设计要求

课程设计总体方案及分析

问题分析

     2.概要设计

3.详细设计

数据结构设计

函数功能设计

调试分析

测试结果

课程设计总结

附录(源代码)


  • 课程设计目的

本课程目的在于充分理解队列的应用,了解队列“先进先出”以及“后进后出“,且只能从一端进入,另一端出去的特点。结合这一特性在众多路线中并行搜索,寻找到能够到达出口的最短路线,提高寻找效率。

  • 课程设计内容和要求

  1. 问题描述

通过自身输入的d*h的迷宫图,规定入口以及出口,且不能重复行走。如果能找到出口,则正向输出从入口到出口的最短路径,反之则该迷宫无解。

      2.设计要求

自己设计迷宫,利用队列求解迷宫问题,且迷宫最外层全为墙。

  • 课程设计总体方案及分析

  1. 问题分析

需要自定义该迷宫的规模(为输入迷宫形状既为了美观,连续输入读取数据,Enter换行换行作为分隔符,只有将数据输入完并按下Enter才执行下一个程序,则使用C++中的cin进行输入迷宫形状,但也需注意C++的头文件),确定墙和路以及入口和出口的位置,将每一个路进行入队操作,且入队的路进行标记,防止重复行走,直至出口位置入队,最后将其最短路径进行正向输出。

     2.概要设计

        为在存储空间的使用上更加高效,选择顺序队列进行迷宫求解。迷宫中用“0“作为路,”1“作为墙, 用i和j记录每一个位置,以及用pre记录前一方块的位置(既找到该方块从哪里来)。将入口先进行入队操作,并将其值置为-1(表示该路已经走过,防止重复行走),非空则进行出队操作,记录出队的数据(i,j,pre),如果不是目标出口则在其四周寻找路,并将其位置(i,j)以及前一方块的位置(pre)入队,并且将其值置为-1,四周入队之后再将对头进行出队操作,直至出口作为队头出队才结束。最后再通过pre寻找最短路径,并将其pre置为-1,再通过pre为-1将其路线正向输出。

    

3.详细设计

  1. 数据结构设计

typedef struct
{
	int i, j, pre;
}Box;
typedef struct
{
	Box data[15];		//队列中存放i,j,pre的数据
	int rear, front;		//队尾指针和队尾指针记录其值
}Q;		//采用顺序队列,高效利用存储空间
  1. 函数功能设计

 

 void InitQ(Q*& qu)          //初始化队列

  bool EmptyQ(Q*& qu)     //用于判断队列是否为空

bool inE(Q*& qu, Box& e)       //进队操作

bool outE(Q*& qu, Box& e)    //出队操作

void print(Q*& qu, int k)         //将找到的最短路径输出打印

bool huan(int xi, int xj, int zi, int zj)        //迷宫的算法路径

void DestroyQ(Q*& qu)                 //使用完后进行销毁,释放空间
  1. 调试分析

C语言中的scanf输入不能实现换行操作,为实现迷宫的换行让其更加美观,可以使用C++中的cin进行输入。

  1. 测试结果

  • 课程设计总结

此次迷宫算法要灵活记录当前位置以及前一方块,通过记录的pre找到最短路径。但是此代码也存在不足,输出的最短路径只有一种,实际上最短路径可以是多种路径,且四个方向先后询问是否为路的顺序也会影响这该怎么走,但是都是最短路径。

附录(源代码)

#include<iostream>

#include<algorithm>

using namespace std;

#define  M 100

#define  N 100

typedef struct

{

       int i, j, pre;

}Box;

typedef struct

{

       Box data[15];

       int rear, front;

}Q;

int m[M][N];

void InitQ(Q*& qu)

{

       qu = (Q*)malloc(sizeof(Q));

       qu->front = qu->rear = -1;

}

bool EmptyQ(Q*& qu)

{

       return(qu->front == qu->rear);

}

bool inE(Q*& qu, Box& e)

{

       if (qu->rear >= 15)

              return 0;

       qu->rear++;

       qu->data[qu->rear] = e;

       return 1;

}

bool outE(Q*& qu, Box& e)

{

       if (EmptyQ(qu))

              return 0;

       qu->front++;

       e = qu->data[qu->front];

       return 1;

}

void DestroyQ(Q*& qu)

{

       free(qu);

}

void print(Q*& qu, int k)

{

       int j;

       while (k != -1)

       {

              j = k;

              k = qu->data[k].pre;

              qu->data[j].pre = -1;

       }

       int g = 0, deng = 0;

       while (g < 15)

       {



              if (qu->data[g].pre == -1)

              {

                     printf("(%d,%d)->  ", qu->data[g].i, qu->data[g].j);

              }

              g++;

       }

       printf("\n");

}

bool huan(int xi, int xj, int zi, int zj)

{

       Box e;

        Q* qu;

        InitQ(qu);

        int i, j, pre;

        e.i = xi, e.j = xj, e.pre = -1;

        m[xi][xj] = -1;

        inE(qu, e);

        while (!EmptyQ(qu))

        {



                outE(qu, e);

                i = e.i, j = e.j, pre = e.pre;

                if (i == zi && j == zj)

                {

                        print(qu, qu->front);

                        return 1;

                }

                int d =0;

                int ni, nj;

                while (d < 4)

                {

                        switch (d)

                        {

                        case 0:ni = i - 1, nj = j;break;

                        case 1:ni = i, nj = j + 1;break;

                        case 2:ni = i + 1, nj = j;break;

                        case 3:ni = i, nj = j - 1;break;

                        }

                        if (m[ni][nj] == 0)

                        {

                                e.i = ni, e.j = nj, e.pre = qu->front;

                                inE(qu, e);

                                m[ni][nj] = -1;

                        }

                        d++;

                }

        }

                DestroyQ(qu);

        return 0;

}

int main()

{

        int i, j;

        int d, h;

        printf("请输入迷宫规格d,h:\n");

        scanf_s("%d%d", &d, &h);

        printf("迷宫形状:\n");

        for (i = 0;i < d;i++)

                for (j = 0;j < h;j++)

                        cin >> m[i][j];

        printf("\n");

        if (huan(1, 1, d-2, h-2) == 0)

                printf("无解");

        printf("\t迷宫逃离出来啦!!!");

        printf("\n");

        return 0;

}

如有不足,欢迎提出嘿嘿。 

标签:pre,Box,课程设计,qu,队列,迷宫,最短,int
From: https://blog.csdn.net/2302_80115666/article/details/139213315

相关文章

  • 【数据结构实验】迷宫问题——线性表
    目录实验目的实验内容(题目) 实验环境 程序代码实验分析 实验目的掌握并理解线性表的存储结构定义,包括线性表的顺序存储结构与链式存储结构。学习并掌握线性表的基本操作实现,如插入、删除、查找、遍历等基本运算。明确线性表的存储结构特点,包括它们的时间和空间复杂......
  • LeetCode/NowCoder-栈和队列OJ练习
    孜孜不倦:孜孜:勤勉,不懈怠。指工作或学习勤奋不知疲倦。......
  • 消息队列
    消息队列​ Linux系统中消息队列(MessageQueue)是进程间通信的一种方式,这种通信机制的好处是可以传输指定类型(用户可以自行定义)的数据,相同类型的数据根据到达顺序在队列中进行排队。​ 不同类型的数据不能处于同一个队列中,也就是说系统中可能存在多个消息队列,每个消息队列中的......
  • python 队列生产者消费者爬虫
    当使用Python编写一个基于队列的生产者消费者爬虫时,我们通常会使用threading或multiprocessing模块来处理并发,并使用queue模块来管理数据队列。下面是一个详细的示例,该示例展示了如何使用生产者线程生成URL,消费者线程爬取这些URL的内容。请注意,这里为了简化示例,我们将不会实际进......
  • 进程间通信(队列和生产消费模型)
    【一】引入【1】什么是进程间通信进程间通信(Inter-ProcessCommunication,IPC)是指两个或多个进程之间进行信息交换的过程【2】如何实现进程间通信借助于消息队列,进程可以将消息放入队列中,然后由另一个进程从队列中取出这种通信方式是非阻塞的,即发送进程不需要等待接收进......
  • 消息队列
    进程A:#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<unistd.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/msg.h>#include<errno.h>#include<string.h>intmsgid;......
  • 数据结构:队列
    目录队列的概念和结构队列的实现结构定义初始化判空入队列出队列返回队头元素返回队尾元素返回size销毁 队列的概念和结构队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstInFirstOut)入队列:进行插入操......
  • 消息队列练习题
    消息队列练习题进程A/**********************************************************************filename:mesqa.c*author:[email protected]*date:2024/5/28*function:接收进程b的信号,读出消......
  • 如果任务过多,队列积压怎么处理?
    如果任务过多,队列积压怎么处理?1、内存队列满了应该怎么办2、问题要治本——发短信导致吞吐量降低的问题不能忽略!!3、多路复用IO模型的核心组件简介1、内存队列满了应该怎么办如图:大家可以看到,虽然现在发短信和广告投递,彼此之间的执行效率不受彼此影响,但是请......
  • 消息队列练习题
    题目:要求进程A创建一条消息队列之后向进程B发送SIGUSR1信号,进程B收到该信号之后打开消息队列并把进程的PID作为消息写入到消息队列中,要求进程B在写入消息之后,发SIGUSR2信号给进程A,进程A收到该信号则从消息队列中读取消息并输出消息正文的内容。进程A的代码://构造用于接收消息......