首页 > 其他分享 >【数据结构实验】迷宫问题——线性表

【数据结构实验】迷宫问题——线性表

时间:2024-05-29 21:33:05浏览次数:22  
标签:rows 线性表 int 路径 迷宫 cols current 数据结构

目录

实验目的

实验内容(题目) 

实验环境

 程序代码

实验分析 


实验目的

  1. 掌握并理解线性表的存储结构定义,包括线性表的顺序存储结构与链式存储结构。
  2. 学习并掌握线性表的基本操作实现,如插入、删除、查找、遍历等基本运算。
  3. 明确线性表的存储结构特点,包括它们的时间和空间复杂性,以及如何根据应用场景选择合适的线性表存储结构。
  4. 通过设计一个解决迷宫问题的算法,本实验不仅旨在将线性表的理论知识应用于具体问题解决过程中,还意在提高分析问题和设计算法的实际能力,为更复杂的数据结构操作和应用打下坚实的基础。

实验内容(题目) 

迷宫问题:迷宫为一个mⅹn的阵列,阵列中的值为0或1(具体数值随机生成),分别表示可以通行(简称“通”)和不可以通行(简称“不通”),左上角(即“(1,1)”)为入口,右下角为出口(即“(m,n)”),每个格点的出行方向有8个。要求:设计一个算法完成找一条从入口到出口的最短路径。

实验环境

(1)软件系统

操作系统:Windows 10

编程环境:Embarcadero Dev-C++ 6.3,包含GNU GCC编译器和GDB调试器

(2)硬件系统

CPU:Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz

内存:16GB

硬盘:500GB SSD

 程序代码

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

// 点结构定义
struct Point {
    int x, y;
    // 步数字段,用于记录从起点到当前点的步数
    int step;
};

// 方向数组,表示点可以移动的8个方向(上下左右以及对角线)
const int directions[8][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};

vector<vector<int> > maze; // 迷宫
vector<vector<bool> > visited; // 访问标记
vector<vector<Point> > path; // 用于回溯路径

// 检查坐标 (x, y) 是否可以进入
bool isValid(int x, int y, int rows, int cols) {
    return x >= 0 && y >= 0 && x < rows && y < cols && maze[x][y] == 0 && !visited[x][y];
}

// BFS 算法找到迷宫的最短路径
bool bfs(int rows, int cols, Point &endPoint) {
    queue<Point> q;
    q.push({0, 0, 0}); // 起点入队
    visited[0][0] = true; // 标记起点已访问

    while (!q.empty()) {
        Point current = q.front();
        q.pop();

        // 到达终点
        if (current.x == rows - 1 && current.y == cols - 1) {
            endPoint = current; // 保存终点信息
            return true; // 找到路径
        }

        // 探索所有可能的方向
        for (int i = 0; i < 8; ++i) {
            int newX = current.x + directions[i][0];
            int newY = current.y + directions[i][1];

            if (isValid(newX, newY, rows, cols)) {
                q.push({newX, newY, current.step + 1});
                visited[newX][newY] = true;
                path[newX][newY] = current; // 记录来时的路径
            }
        }
    }

    return false;
}

// 从终点递归回溯到起点,并打印路径
void printPath(Point endPoint) {
    if (endPoint.x == 0 && endPoint.y == 0) {
        cout << "(" << endPoint.x + 1 << ", " << endPoint.y + 1 << ")";
        return;
    }
    printPath(path[endPoint.x][endPoint.y]);
    cout << " -> (" << endPoint.x + 1 << ", " << endPoint.y + 1 << ")";
}

int main() {
    int rows, cols;
    cout << "请输入迷宫的行数:";
    cin >> rows;
    cout << "请输入迷宫的列数:";
    cin >> cols;

    // 初始化迷宫和访问标记
    maze.resize(rows, vector<int>(cols));
    visited.resize(rows, vector<bool>(cols, false));
    path.resize(rows, vector<Point>(cols));

    cout << "请输入迷宫矩阵(0代表可通行,1代表不通行):" << endl;
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            cin >> maze[i][j];
        }
    }

    Point endPoint;
    if (bfs(rows, cols, endPoint)) {
        cout << "找到路径,路径如下:" << endl;
        printPath(endPoint);
        cout << endl << "总共需要步数:" << endPoint.step << endl;
    } else {
        cout << "未找到路径。" << endl;
    }

    return 0;
}

注意事项:

我使用的是DEVC++5.11,同学们如果遇到中文无法输入、显示乱码导致编译不通过的现象,只需要将编译器gcc设置为32位:

实验分析 

从以下方面分析:

1、正确性(输入的测试数据和测试结果,附测算截屏)

此代码使用了广度优先搜索(BFS)算法,它能够保证找到从起点到终点的最短路径,如果迷宫中存在一条路径。BFS通过探索最近的未访问邻居节点,并逐步扩展到更远的节点来工作。一旦到达终点,算法就会停止,确保了找到的路径是最短的。在回溯打印路径时,printPath 函数从终点递归地回溯到起点,保持了路径的连续性和正确性。

测算截屏:

2、可读性(主要在源代码中体现)

代码的可读性良好,因为使用了自解释的变量名和结构,且函数功能单一明确。例如,isValid 函数用于检查一个点是否可以进入,bfs函数用于执行宽度优先搜索,而 printPath 函数用于输出路径。同时,所有函数和数据结构都有清晰的注释,易于理解其用途。

3、健壮性(容错性,主要在源代码中体现,在此简要说明)

代码的健壮性表现在它能够处理无法到达终点的情况,并给出相应的输出信息。输入被严格限制在迷宫的边界内,且所有的vector都被初始化,这减少了出错的可能性。程序没有采用异常处理结构来处理输入错误等问题,这是未来改进的一个方向。

4、时间和空间复杂度(针对核心算法函数分析)

  • 时间复杂度:广度优先搜索的时间复杂度为O(V + E),其中V是顶点(迷宫中的单元格)数量,E是边的数量(在迷宫中,一个单元格可以最多与8个其他单元格相连)。在最坏的情况下,时间复杂度为O(n*m),其中n和m分别是迷宫的行数和列数。
  • 空间复杂度:空间复杂度也是O(n*m),因为需要存储每个单元格的访问状态和来时的路径。此外,队列在最坏的情况下可能需要存储所有的单元格,如果迷宫几乎都是0(完全开放),则在队列中的元素数量将接近单元格的总数。

 

标签:rows,线性表,int,路径,迷宫,cols,current,数据结构
From: https://blog.csdn.net/weixin_64259675/article/details/139305649

相关文章

  • cadical基本数据结构分析2
       1.文字、变元变元和文字iteration: vars,litsvals: signedchar*vals;//assignment[-max_var,max_var]//Internal数据成员,保存文字的赋值-同时其对应负文字的赋值也一并保存(更新)。//可以理解......
  • Java数据结构与算法(红黑树)
    前言红黑树是一种自平衡二叉搜索树,确保在插入和删除操作后,树的高度保持平衡,从而保证基本操作(插入、删除、查找)的时间复杂度为O(logn)。实现原理红黑树具有以下性质:每个节点要么是红色,要么是黑色。根节点是黑色的。每个叶子节点(NIL节点,通常是空节点)是黑色的。如果一个节点......
  • Java数据结构与算法(散列表)
    前言散列表是根据关键码值(Keyvalue)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。而key的冲突主要通过链表的方式来处理,后期链表过长情况下可以通过红黑树来优化查询效率。实现原理散列函数(HashFunction):散列函数......
  • Java数据结构与算法(B+树)
    前言B+树(B+Tree)是一种平衡树数据结构,广泛用于数据库和文件系统中。它是一种自平衡的树结构,每个节点包含多个键,并且所有键都是排序的。B+树的叶子节点包含指向相邻叶子节点的指针,这使得范围查询非常高效。B+树的优点1.由于B+树在非叶子结点上不包含真正的数据,只当做索引使用......
  • 【python数据结构4】基于栈结构的简单括号匹配
    我们现在把注意力转向使用栈解决真正的计算机问题。你会这么写算术表达式(5+6)*(7+8)/(4+3)其中括号用于命令操作的执行。你可能也有一些语言的经验,如Lisp的构造(defunsquare(n)(*nn))这段代码定义了一个名为square的函数,它将返回参数的n的平方。Lisp......
  • 为什么算法和数据结构重要?
    算法的重要性 效率提升:优秀的算法可以显著提高程序的执行效率,减少运行时间。解决复杂问题:算法提供了解决复杂问题的系统方法,如排序、大规模数据处理、路径规划等。优化资源使用:通过优化算法,可以更好地利用计算资源,如内存和处理能力。 数据结构的重要性 数据组织:良......
  • 探索数据结构:单链表的实践和应用
    ......
  • kbgressdb之数据结构V0.2
    前言原本计划2024.05.01日开始编码,直到2024.05.21日才开始编码,因为在2024.05.19日才感觉体力恢复到了九成,然后就开始kbgressdbV0.2版本设计,经过一周的推演与构思,终于在2024.05.29日完成V0.2版本设计。为什么把大量精力放在kbgressdb数据结构上?或许你会有此一问,因为这个kbgressdb......
  • 考研复试问答-操作系统&数据结构
    操作系统中断的分类中断使CPU从用户态变为内核态,让操作系统内核强行收回CPU的控制权。中断分为内中断和外中断,内中断主要包括异常,比如自陷指令、地址越界、计算溢出;外中断主要是包括来自时钟以及I/O的中断;分时操作系统:时间片轮转,强调交互性实时操作系统:强调可靠性,分为硬实时......
  • C++数据结构之Hash table(哈希表|散列表)
    目录一、基本组成部分二、使用方法 三、代码实现四、代码中如何遍历链表来避免冲突哈希表(HashTable),也称为散列表(思考:vs平衡二叉树),是一种数据结构,它提供了通过键(key)直接访问存储的值(value)的能力。哈希表的工作原理基于哈希函数(HashFunction),该函数将输入的键映射到表中的......