【C++】使用栈Stack解决迷宫问题

我们看下面这个迷宫----方阵(也可以是矩阵):

迷宫入口是坐标(2,0)位置,出口是(9,3)。我们假定0代表通路,1代表不通。

现在需要找到哪一条路是通路。我们的思想是借助栈,“回溯法”。回溯是什么意思呢???先从起点出发,检查它的上下左右是否是通路(即是否有为数字0处)。也就是说为0通了,压栈,将此位置元素变成2,这样做的好处是明确通路路径。然后继续往下走,判断上下左右 。直至我们找到终点(纵坐标在矩阵的最后一行)。

我们来看下我针对迷宫问题实现的代码:


#include<stack>
#include<assert.h>
#define N 10    //该迷宫10*10.

struct Pos    //定义一个结构体,该结构体用来表示坐标。
{
    int _row;
    int _col;

    Pos(int row,int col)
        :_row(row)
        , _col(col)
    {}
};

template<class T>
bool SearchMazePath(int* a, int n, Pos entry, stack<T>& paths)    //寻找迷宫是否有通路。
{
    assert(a);
    
    paths.push(entry);
    while (!paths.empty())
    {
        Pos cur = paths.top();
        a[cur._row*n + cur._col] = 2;            
        if (cur._row == n - 1)
        {
            return true;
        }

        //上
         Pos tmp = cur;
        --tmp._row;
        if (a[tmp._row*n + tmp._col] == 0)
        {
            paths.push(tmp);
            continue;
        }
        
        //下
        tmp = cur;    
        ++tmp._row;
        if (a[tmp._row*n + tmp._col] == 0)
        {
            paths.push(tmp);
            continue;
        }
        
        //左
        tmp = cur;        
        --tmp._col;
        if (a[tmp._row*n + tmp._col] == 0)
        {
            paths.push(tmp);
            continue;
        }
        
         //右
       tmp = cur;
        ++tmp._col;
        if (a[tmp._row*n + tmp._col] == 0)
        {
            paths.push(tmp);
            continue;
        }
        
        paths.pop();    //若上下左右都不通,则回溯。
    }
    
    return false;
}

void GetMaze(int* a, int n)    //读取到迷宫图案
{
    assert(a);
    FILE* fout = fopen("MazeMap.txt", "r");
    assert(fout);    //若文件打开失败,后续工作则无法完成,因此采用assert防御式编程。
    
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            while (true)
            {
                int men = fgetc(fout);    //读取字符
                if (men == ‘0‘ || men == ‘1‘)    //是0或者1则转换成数字到二维矩阵中存储。
                {
                    a[i*n + j] = men -‘0‘;
                    break;    
                }                
            }
        }
    }       
}

void PrintMaze(int* a, int n)    //将此迷宫打印出来
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n;j++ )
        {
            cout << a[i*n + j] << "  ";
        }
        cout << endl;
    }
    cout << endl;
}

void Test()
{
    int a[N][N] = {};
    Pos sp(2, 0);    //入口坐标
    
    GetMaze((int*) a, N);
    PrintMaze((int*)a, N);
    stack<Pos> paths;
    
    SearchMazePath((int*)a, N, sp, paths);  
    //二维数组实际存储是一维数组,将二维数组强制转换为一维数组传参。
    PrintMaze((int*)a, N);
}

int main()
{
    Test();
    system("pause");
    return 0;
}

有时候,针对迷宫问题,我们还需要求多条路径的最优解(最短路径)。那这时候我们可以用压栈,利用栈帧一层一层压栈的特点实现。

时间: 2024-08-25 14:44:25

【C++】使用栈Stack解决迷宫问题的相关文章

栈的应用-迷宫解题

总结:这个是网上找的,下面一个是我在他基础上修改的. /* 二. 栈的应用-迷宫解题 */ #include<stdio.h> #include<malloc.h> #include<stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 //坐标类型 typedef struct { int x; in

(转)堆heap和栈stack

一 英文名称 堆和栈是C/C++编程中经常遇到的两个基本概念.先看一下它们的英文表示: 堆――heap 栈――stack 二 从数据结构和系统两个层次理解 在具体的C/C++编程框架中,这两个概念并不是并行的.深入到汇编级进行研究就会发现,栈是机器系统提供的数据结构,而堆是由C/C++函数库提供的.这两个概念可以从数据结构和系统两个层次去理解: 1.从数据结构层次理解,栈是一种先进后出的线性表,只要符合先进后出的原则的线性表都是栈.至于采用的存储方式(实现方式)是顺序存储(顺序栈)还是链式存储(

Python 栈(stack)

Python 栈(stack) 栈(stack)又名堆栈,它是一种运算受限的线性表 栈只能在一端进行插入和删除操作,它按照先进后出(FILO)的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶 栈也可以看成是 FILO 的队列 <- 点击查看 操作 进栈 出栈 取栈顶 示例: class Stack(object): def __init__(self): self.stack = [] def push(self, data): """ 进栈函数 "&

【算法题】06-用栈来解决汉诺塔问题

用栈来解决汉诺塔问题 题目 修改汉诺塔问题的游戏规则:限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动和最优移动总步数. 要求: 方法一:递归的方法 方法二:非递归的方法,用栈来模拟汉诺塔的三个塔 思路 方法一:递归的方法 首先,如果只剩最上层的塔需要移动,则有如下处理: 如果希望从左移动到右,打印Move 1 from left to right 如果希望从中移动到左,打印Move 1 from mid to left 如

JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令)2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身栈区:1.每个线程包含一个栈区,栈中只保存基础数

.NET中的堆(Heap)和栈(Stack)的本质

计算机的内存可以分为代码块内存,Stack内存和Heap内存.代码块内存是在加载程序时存放程序机器代码的地方. 栈(Stack)一般存放函数内的局部变量. 堆(Heap)一般存放全局变量和类对象实例等. 若只是声明一个对象,则先在栈内存中为其分配地址空间,若再实例化它,则在堆内存中为其分配空间. 1.Stack VS Heap 由于计算机的内存分配过程比较抽象,下面举一个简单的程序片段,来图解和谐步骤对Stack和Heap内存的影响: 下面的StackVsHeap类有一个Person类和Fun1

Java里的堆(heap)栈(stack)和方法区(method)

基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量 . 方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完成后从栈空间回收.局部变量 new 出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收. 方法调用时传入的 literal 参数,先在栈空间分配,在方法调用完成后从栈空间分配.

栈的运用---迷宫

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

栈Stack和段寄存器SS,SP(学习汇编)

1. 栈有2个基本操作:入栈.出栈 2. 栈顶的元素总是最后入栈,最先出栈:后进先出. 3. 8086CPU提供入栈和出栈的指令,最基本的两个是 PUSH(入栈) 和 POP(出栈) push ax 表示将AX寄存器的内容送入栈中, pop ax 表示从栈顶取出数据送入AX寄存器中.     8086CPU的入栈和出栈操作都是以字(word)为单位的. 4. 8086CPU中,段寄存器SS:存放栈顶段地址,段寄存器SP: 存放栈顶的偏移地址. 5. 任意时刻:SS:SP 指向栈顶元素. 6. 8