数据结构之迷宫求通路《回溯法与栈》

来源:互联网 发布:巨人网络最新消息 编辑:程序博客网 时间:2024/05/02 14:21

关于回溯与栈的最初的迷茫之处:刚开始听完迷宫问题求通路的时候,我就有一个疑问:将文件的内容传递给数组,再进行压栈,这两个(数组与栈空间)明明不是同一块空间,为什么当我释放栈的时候,当前路径的尾节点能够变为上一个节点,从而使得上一个节点成为了新路径的尾节点 ?《希望你们能看懂我说的什么意思,嘿嘿》,如果就这么用文字描述答案虽然能说通但是印象并不会太深刻,所以不说废话了。直接上代码。

//Stack.h  :这里我自己实现的模板栈#pragma once #include<iostream>#include<assert.h>using namespace std;template<class T>class Stack{public:    Stack()        :_a(new T[1])        ,_sz(0)        ,_capacity(0)    {}    ~Stack()    {        if(_a)        {            delete[] _a;            _sz = 0;            _capacity = 0;        }    }public:    void Push(const T& d);    void CheckCapacity();       bool Empty();    void Pop();    T& Top();    void Dislplay();protected:    T* _a;    int _sz;    int _capacity;};template<class T>void Stack<T>::CheckCapacity (){    if(_sz == _capacity )    {        T* tmp =new T[_capacity * 2+ 3];        for(int i = 0; i < _sz;i++)        {            tmp[i] = _a[i];        }        delete[] _a;        _capacity = _capacity * 2 + 3;        _a = tmp;    }}template<class T>void Stack<T>::Push(const T& d){    CheckCapacity();    _a[_sz] = d;     _sz++;}template<class T>void Stack<T>::Pop(){    assert(_sz > 0);    _sz--;}template<class T>T& Stack<T>::Top(){    return _a[_sz-1];}template<class T>bool Stack<T>::Empty(){    return _sz == 0;}template<class T>void Stack<T>::Dislplay (){    for(int i = 0;i<_sz ;i++)    {        cout<<_a[i]<<" ";    }    cout<<endl;}
//Maze.h#pragma once#include"stack.h"#define N 10void InitMaze(int *m) //从文件中读取数据到数组Maze中{    FILE* fout = fopen("Maze.txt","r");    for(int i = 0; i < N;i++)    {        for(int j = 0; j< N ;)        {            char value = fgetc(fout);            if(value == 32|| value == 10)                continue;            m[i*N+j] =  value - '0';            ++j;        }    }}struct Pos  {    int _row;    int _col;};bool CheckPos(int row,int col,Pos p,int *m)//只有当数据为0的时候才考虑上下左右{    if((p._row >= 0) &&(p._row < row)&&(p._col >= 0)&&(p._col < col)&&(m[p._row * N+ p._col]==0))        return true;    return false;}bool Through(int row,int col,Pos next){    if((next._row == row-1)||(next._col == col-1))        return true;    return false;}bool GetPath(int row,int col,int* m,Stack<Pos>& s,Pos enter){    s.Push (enter);    m[enter._row * N+enter._col ] = 2;    while(!s.Empty ())    {             Pos cur = s.Top ();//cur为最新压入栈中的数据,栈顶的元素就是迷宫目前能走的最后一步        Pos next = cur;//是以当前节点为中心进行上下左右节点测试的坐标变量        //上        next._row = next._row -1;//next就是坐标,栈存放的就是数组的坐标,当路径被封死,就要释放栈顶,**每当pop()后**next要在该节点(此处不是pop()的节点)进行上下左右的分析,来判断是否有下一个可以走的节点,若没有,则继续pop(),不断的往该节点的上一个节点走,**这就是回溯**。直到某一个尾节点的上下左右有通路,再从新进行探索。        //回到最前面的问题:压栈的是数组元素的坐标,当栈被释放,因为next发生改变。所以m[next._row *N+next._col ]就成为了上一个节点,所以当我释放栈的时候,当前路径的尾节点能够变为上一个节点,从而使得上一个节点成为了新路径的尾节点         if(CheckPos(row,col,next,m))        {            s.Push (next);            m[next._row *N+next._col ]=2;            continue;        }        next._row = next._row +1;        next._row = next._row +1;         //if(CheckPos(row,col,next,m))        {            s.Push (next);            m[next._row *N+next._col ]=2;            continue;        }        next._row = next._row -1;        next._col = next._col -1;         //if(CheckPos(row,col,next,m))        {            s.Push (next);            m[next._row *N+next._col ]=2;            continue;        }        next._col = next._col +1;        next._col = next._col +1;        //if(CheckPos(row,col,next,m))        {            s.Push (next);            m[next._row *N+next._col ]=2;            continue;        }        next._col = next._col -1;                if(Through(row,col,next))            return true;        s.Pop ();                         //当上下左右都无法走的时候    }    return false;}void PrintMaze(int* m){        for(int i = 0; i < N;i++)    {        for(int j = 0; j< N ;j++)        {            cout<<m[i*N+j]<<" ";         }        cout<<endl;    }        cout<<endl;}
//Maze.cpp#include"stack.h"#include"Maze.h"    using namespace std;void test(){    Stack<int> s1;    s1.Push (1);    s1.Push (2);    s1.Push (3);    s1.Push (4);    s1.Push (5);    s1.Dislplay ();    cout<<s1.Empty() <<endl;    cout<<s1.Top()<<endl;    s1.Pop ();    s1.Dislplay ();}void MazeTest(){    Stack<Pos> s1;    Pos e ;    e._row = 1;    e._col = 0;    int maze[N][N];    InitMaze((int*)maze);    PrintMaze((int*)maze);    GetPath(N,N,(int*)maze,s1,e);    PrintMaze((int*)maze);}int main(){    //test();    MazeTest();    return 0;}

这里写图片描述

0 1
原创粉丝点击