迷宫问题(栈)

"迷宫问题(栈)"

“栈”是一种简单的数据结构,它的主要特点就是"先进后出",即就是先压入栈中的数据需要最后出栈。相当于栈是一个杯子,最先放进栈中的东西,只能够最后拿出来。下面对“栈”的特点用图形象的表示出来。

这次所要讨论的是基于栈的迷宫问题,当给定一个迷宫,我们怎样能够找出迷宫中的通道呢?如果迷宫的规模比较大,我们又该如何去实现呢?我们能够明显的知道需要使用一个二维数组用来保存迷宫,但是当迷宫的规模比较大时,或者是当我们想要频繁的去更改所设计的迷宫时,用二维数组的方式显然是不大合理,程序更改会比较麻烦。

在这里我采用“文件”的方式将迷宫进行保存,程序中只用实现读取文件的操作,这样很便于以后对程序的维护。因为动态的给定迷宫大小,程序的实现还是较为麻烦的,这里直接将迷宫的规模给定。用“1”来表示不能够通过,“0”表示能够通过。下面是迷宫的设计:

针对迷宫的特点,主要采用的方法是先将迷宫的入口点压入栈中,在对这个点的上、下、左、右方向的节点进行判断,看是否有能够通过的节点(“0”),若没有,则迷宫中没有一条能够通过的路径,如果存在,则将这个节点也压入栈中,循环这种方式,直到找到没有能够前进的点,此时就要进行“回溯”, 即就是倒回以前走过的点。进而在判断有没有刚才没有走过的且能够通过的节点,若存在,再次进行刚才的压栈操作,直到走出迷宫,若回到迷宫的入口点,则迷宫中不存在通路。

根据上面的思路,编写出下面的代码:

//memory.h文件

#pragma once
#define MAX 10
#include <stack>
#include <assert.h>

//使用静态数组
struct pos     //标记点的位置坐标
{
   int _row;
   int _col;
};

void GetMaze(int * arr, int n)      //从文件中获取迷宫
{
   assert(arr);
   FILE* open = fopen("F:\\keshe\\迷宫问题(栈)\\MazeMap.txt", "r");
   assert(open);    //判断打开文件是否成功
   for (int i = 0; i < MAX; i++)
   {
      for (int j = 0; j < MAX; )
     {
        char ch = fgetc(open);
        if (ch == ‘1‘ || ch == ‘0‘)
        {
           arr[i * n + j] = ch - ‘0‘;
           j++;                            //为了防止迷宫中行与列之间的间距
         }
      }
   }
   fclose(open);
}

void print(int * arr, int n)      //打印迷宫
{
   for (int i = 0; i < MAX; i++)
   {
      for (int j = 0; j < MAX; j++)
      {
         cout << arr[i * n + j] << " ";
       }
      cout << endl;
   }
}

bool checkIsAccess(int * arr, int n, const pos& next)  //检查迷宫节点的下一个路径上的节点
{
    assert(arr);
    if (next._row >= 0 && next._row < MAX && next._col >= 0 && next._col <= MAX
         && arr[next._row * n + next._col] == 0)
    {
       return true;
    }
    return false;
}

//entry 为入口的位置,Paths用来保存迷宫的通路
//判断迷宫中是否存在一条通路
bool SearchMazePaths(int * arr, int n, pos entry, stack<pos> & Paths)  
{
    assert(arr);
    Paths.push(entry);
    while (!Paths.empty())
   {
      pos cur = Paths.top();
      arr[cur._row * n + cur._col] = 2;    //将压栈后的位置内容进行更改
      if (cur._row == (n - 1))
      {
         return true;
      }
      pos next = cur;
      
      //上
      next._row--;
      if (checkIsAccess(arr, n, next))
      {
          Paths.push(next);
          continue;
      } 
      
     //下
     next = cur;
     next._row++;
     if (checkIsAccess(arr, n, next))
     {
         Paths.push(next);
         continue;
     }
     
     //左
     next = cur;
     next._col--;
     if (checkIsAccess(arr, n, next))
     {
        Paths.push(next);
        continue;
     }
     
     //右
     next = cur; 
     next._col++;
     if (checkIsAccess(arr, n, next))
     {
        Paths.push(next);
        continue;
     }
     Paths.pop();     //若节点的剩余方向都不能通过,则进行回溯。
   }
}
//test.cpp文件

#define _CRT_SECURE_NO_WARNINGS 1
//使用栈来设计迷宫问题
#include <iostream>
using namespace std;
#include <stdlib.h>
#include "memory.h"

int main()
{
    int arr[MAX][MAX] = { 0 };
    stack<pos> Paths;
    pos tmp;
    tmp._row = 2;
    tmp._col = 0;
    
    GetMaze((int*)arr, MAX);
    print((int*)arr, MAX);
    cout << endl << endl;
    
    int ret = SearchMazePaths((int *)arr, MAX, tmp, Paths);
    printf("能否有一条通路:%d\n\n\n", ret);
    print((int*)arr, MAX);
    
    system("pause");
    return 0;
}
时间: 2024-12-28 01:41:56

迷宫问题(栈)的相关文章

迷宫问题求解(一)利用栈与递归求解出口

本文适合于对迷宫问题已有初步研究,或阅读代码能力较强的人. 因此,如果你对迷宫问题一无所知,请参考其他更详细的资料. 迷宫问题,是一个对栈(Stack)典型应用的例子之一. 假如,有如下10X10的迷宫(0代表通路,1代表障碍),我们需要用写程序来找出迷宫的出口. 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 0 1 1 0 1 0 0 1 1 1 0 1 0 0 1 0 1 1 1 1 0 1 1 1 1 0 0

day40 数据结构-算法(二)

什么是数据结构? 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中. 比如:列表.集合与字典等都是一种数据结构. N.Wirth: "程序=数据结构+算法" 列表 列表:在其他编程语言中称为"数组",是一种基本的数据结构类型. 关于列表的问题: 列表中元素使如何存储的? 列表提供了哪些基本的操作? 这些操作的时间复杂度是多少? 列表与可变对象* 栈 栈(Stack)是一个数据集合,可以理解为只能在一端进行插入或删除操作的列表. 栈的特点:后进先出(las

七方件业金离以提领前群约会ODjdidtlwfWv

为了从不同环节,尤其与广大使用人群直接关系的环节反映质量状况,对共享自行车投放点.运营仓库.生产企业等不同环节的产品抽查,覆盖了共享自行车从成品出厂到待投放的关键环节. 该负责人称,根据新车投放情况,结合共享自行车行业市场占有分布特点,本次重点抽查了摩拜.ofo.Hellobike三个品牌的产品,占本次抽查批次总数的83.3%.其中,在天津.无锡.武汉.广州.深圳.东莞6个城市抽查了9批次摩拜产品,占产品抽查批次总数的37.5%,抽查批次合格率88.9%,抽查不合格的1批次产品为待投放于广州市的

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

初级版迷宫问题(栈的应用)

  /*  (一)初级迷宫问题:   0:代表通   1:代表不通   求迷宫的通路  (二)步骤:   1.创建迷宫      * 从文件中读取迷宫      * 开辟二维数组存放迷宫   2.寻找通路      * 检查某位置是否为通      * 出口位置判断      * 走过的路用2标记      * 利用栈回溯  (三)问题   1.解决回溯中重复探测:递归   2.最优解:迷宫的最短通路 */ #include <iostream> #include <stdlib.h&g

迷宫问题(一)-利用栈回溯

本题的前提:起点(1,1), 终点(8,8) #include<stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -1 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 20 #define N 10 typedef int Status; typedef char Ma

栈与回溯:迷宫问题

迷宫问题是栈的典型应用,栈通常也与回溯算法连用. 回溯算法的基本描述是: (1)  选择一个起始点: (2)  如果已达目的地, 则跳转到 (4): 如果没有到达目的地, 则跳转到 (3) ; (3)  求出当前的可选项: a.  若有多个可选项,则通过某种策略选择一个选项,行进到下一个位置,然后跳转到 (2); b.  若行进到某一个位置发现没有选项时,就回退到上一个位置,然后回退到 (2) ; (4) 退出算法. 在回溯算法的实现中,通常要使用栈来保存行进中的位置及选项.本文给出自己写的迷宫

栈实现迷宫求解(c++版)

相信大家都应该听过栈吧,一直想利用栈来实现一个算法,最近有点空,就利用栈的先进后出的特性来完成迷宫求的问题,下面将详细介绍栈的实现和迷宫求解的过程,可以很好的学习栈的使用. 栈有两种实现方法,一种是顺序,即数组形式,一种是线性,即链表形式,个人还是比较喜欢链表形式实现栈的基本功能. 首先弄一个简单的迷宫,如图: 我们很容易看出这个迷宫解的路径,那怎么让计算机帮我们求解出来呢. 首先我们要对迷宫数据化,很容易想到二维数组来表示,0表示通路,1表示障碍,即表示为: int map[4][4]={ {

用栈实现的迷宫问题

迷宫问题中为了保证任何位置上都能沿原路退回,显然需要用一个先进后出的结果来保存从入口到当前位置的路径.因此,在迷宫通路的算法中应用“栈”也是自然而然的事情 头文件: #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 i

栈的运用---迷宫

实验2-1 栈与迷宫求解 [实验目的] 1.熟悉C语言的上机环境VC6,掌握C语言程序设计方法与特点. 2.掌握栈的顺序存储结构的定义及C语言实现. 3.掌握栈的顺序存储结构上的各种基本操作. 4.应用栈实现迷宫通路算法. 5.迷宫求解的关键结构定义及C语言实现. [问题说明] 一个迷宫可用n阶方阵表示,1表示能通过,0 表示不能通过.现假设老鼠从左上角[1,1]进入迷宫,编写算法,寻求一条从右下角[n,n] 出去的路径.下图是一个迷宫的示意图: 迷宫示意图 [算法基本思想] 迷宫求解是栈的一个