数据结构之迷宫求通路《回溯法与栈》
来源:互联网 发布:巨人网络最新消息 编辑:程序博客网 时间: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
- 数据结构之迷宫求通路《回溯法与栈》
- 回溯法求迷宫
- 求迷宫通路问题
- 回溯法求迷宫问题
- 回溯法求迷宫问题
- 回溯法求迷宫问题
- 数据结构学习之回溯法求解迷宫问题
- 回溯法之迷宫 栈的引用
- 【数据结构】用回溯法求解迷宫问题
- 数据结构-迷宫问题(回溯法)
- 数据结构与算法学习之路:迷宫问题——回溯思想找出所有路径
- (回溯法) 数据结构_回溯法求解迷宫路径
- 数据结构之回溯法
- 数据结构 迷宫的非递归实现(回溯法)
- 回溯法 -数据结构与算法
- 回溯法 -数据结构与算法
- 回溯法 -数据结构与算法
- SDUT_2449_数据结构实验之栈与队列十:走迷宫
- CCF 画图
- MapReduce算法形式四:mapjoin-reduce端的
- 网站用户并发数问题
- nginx学习(二)——基础概念之异步非阻塞
- 感知机算法原理及代码实现
- 数据结构之迷宫求通路《回溯法与栈》
- 101. Symmetric Tree
- MapReduce算法形式五:TOP—N
- ubuntu 安装opencv 2.4.13
- Linux进程间通信的几种方式
- android开机引导导航功能ViewPager
- JVM 类加载器
- java的concurrent用法详解
- 编写第一个Android Native Service