栈实现迷宫

来源:互联网 发布:粒子群优化算法 编辑:程序博客网 时间:2024/06/05 02:04

        栈的类型定义:栈是一种特殊的线性表,限定只能在表的一端进行插入和删除操作的线性表。在表中,允许插入删除的一端称为“栈顶”,不允许插入删除的另一端称为“栈底”,没有元素的栈称为空栈,插入元素称为入栈,删除元素称为出栈,称为先进后出。


        顺序栈类型的定义:顺序栈的存储方式是数组,需要事先为他分配一个可容纳最多元素的存储空间,“栈顶指针”意为指示栈顶元素在栈中的位置,在栈的长度已知的情况下,这个值也实际上反应了栈中元素的个数,和顺序表中的length的意义相同


#include<iostream>#include<class T>class SeqStack  //顺序栈{private:T *element;  //动态数组存储栈的数组元素int size;  //栈的数组容量int top;   //栈顶元素下标public:SeqStack (int size = 64);  //构造指定容量的空栈~SeqStack ();  //析构函数bool isEmpty();  //判断是否空栈void push(T x);  //入栈T pop();   //出栈T getTop();  //返回栈顶元素,未出栈friend ostream& operator<<(ostream& out,SeqStack<T>&stack);  //输出栈};template<class T>SeqStack<T>::SeqStack (int size){this->size = size<64?64:size;this->element = new T[this->size];this->top=-1;}template <class T>SeqStack<T>::SeqStack(){   delete []element;}template <class T>bool SeqStack<T>::isEmpty(){   return top==-1;}template<class T>void SeqStack<T>::push(T x){   if(top == size-1)  //栈满   {       T *temp = element;  element = new T[size*2];  for(int i=0;i<size;i++)  element[i] =temp[i];  size*=2;   }   top++;   element[top] = x;}template <class T>T SeqStack<T>::getTop(){   if(!isEmpty())  return element[top];   throw "空栈,不能获得栈顶元素";}template<class T>T SeqStack<T>::pop(){   if(!isEmpty())   {       T x =element[top];  top--;  return x;   }   throw "空栈,不能执行出栈顺序";}template<class T>{   if(!isEmpty())   {      T x=element[top]; top--; return x;   }   throw"空栈,不能执行出栈操作";}template <class T>ostream& operator<< (ostream& out,SeqStack<T>&stack){out<<"SeqStack:(";if(!stack.isEmpty()){  for(int i=0;i<stack.top;i++)  out<<stack.element[stack.top];  out<<stack.element[stack.top];}out<<")\n";return out;}




        链式栈:链式栈是栈的链式储存结构,链式栈的结构结点结构和单链表的结点结构相同。由于栈只有栈顶作插入和删除操作,因此链式栈中不需要头结点,但要注意链式栈中指针是指向栈顶的,方向是从栈顶指向栈底的,这正好与单链表是相反的。单链表的第一个结点为栈顶结点,指针top指向栈顶结点。出栈操作时删除栈顶结点并返回栈顶元素,入栈操作时在栈顶结点前插入新结点,并指向指针top指向这个新结点,获得栈顶元素。


#include<iostream>#include"SingleNode.h"  //单链表结点类template <class T>class LinkedStack{private:Node<T> *top;  //指向栈顶结点的指针public:LinkedStack();~LinkedStack();bool isEmpty();void push(T x);T pop();T getTop();  //返回栈顶元素,尾出栈friend ostream& operator<<(ostream& out,LinkedStrack<T>&stack);};template<class T>LinkedStack<T>::LinkedStack(){  top = NULL;}template <class T>LinkedStack<T>::~LinkedStack(){   Node<T> *p=top,*q;   while(p!=NULL)   {     q=p;p=p->next;delete q;   }   top = NULL;}template<class T>bool LinkedStack<T>::isEmpty(){   return top==NULL;}template<class T>void LinkedStack<T>:;push(T x){   top = new Node<T>(x,top);}template <class T>T LinkedStack<T>::pop(){  if(!isEmpty())  {    T x = top->data;Node<T> *p = top;top =top ->next;delete p;return x;  }  throw "空栈,不能执行出栈操作";}template<class T>T LinkedStack<T>::getTop(){  if(!isEmpty()) return top->data;  throw "空栈,不能获得栈顶元素";}template <class T>ostream&operator<<(ostream& out,LinkedStack<T>&stack)  //输出栈{out<<"LinkedStack:(";Node<T> *p=stack.top;while(p!=NULL){  out<<p->data;  p=p->next;  if(p!=NULL)  cout<<",";}out<<")"<<endl;return out;}



        求迷宫中一条路径的算法的基本思想:若当前位置“可通”,则纳入“当前路径”将当前位置亚茹栈中,并记录下一位置在当前位置的什么方位,走到下一位置继续探索,若当前位置不可通,则应顺着来的方向退回到当前一位置,然后朝着除来向只外的其他方向继续探索;若该通道快的四周四个方向均不可通,则应从当前路径上删除位置   1.设当前位置的初值为入口位置  2.入口位置压入栈顶  3.判断是否为空,若非空则(1)取出栈顶元素,取得出发位置(2)东西南北四个方向探索:从东开始,沿顺时针分别取相邻位置信息 a.如果可到达,则当前位置的前一位置信息压入栈顶,判断当前位置是否是出口位置,如果是出口位置,到达出口,探路成功;否则从当前位置开始,东西南北四个方向继续探索。


#define _CRT_SECURE_NO_WARNINGS #include<iostream>#include"LinkedStack.h"int const max=100;int const m = 6;int const n = 8;int maze[m+2][n+2] ={{1,1,1,1,1,1,1,1,1,1},{1,0,1,1,0,1,1,1,1,1},{1,0,0,1,0,1,1,1,1,1};{1,1,0,0,0,0,0,0,1,1};{1,0,1,1,1,1,0,1,1,1};{1,1,0,0,1,1,0,0,0,1};{1,0,1,1,0,0,1,1,0,1};{1,1,1,1,1,1,1,1,1,1};};class Direction{public:int x,y;Direction(int xx,int yy){  x= xx;  y= yy;}};class Point{public:int x,y,d;};int path(LinkedStack<Point>*s, int maze[8][10], int startX,int startY, int endX,int endY){Direction directon[4] = {Direction(0,1),Direction(1,0),Direction(0,-1),Directon(-1,0);}  //右,下,左,上四个方位Point temp;int x,y,d,i,j,sort=2;temo x=startX;temp y=startY;maze[startX][startY] =2;temp.d = -1;//初始化入口坐标s->push(temp);while(!s->isEmpty())  //判断栈是否为空{  temp=s->pop();  x=temp.x;  y=temp.y;  d=temp.d+1;  while(d<4)//开始做各个方向的测试  {     i=x+direction[d].x; j=y+direction[d].y; if(maze[i][j]==0)//判断是否可以到达 {    temp.x=x;temp.y=y;temp.d=d;//将可到达的坐标传递给临时变量temp             s->push(temp);x = i;y = j;maze[x][y]=++sort;//到达新坐标,将新坐标标为累加,从开始时走过的坐标if(x = endX && y = endY)return 1;elsed = 0;//重新初始化方向 } else d++;  }}   return 0;  //迷宫无路返回失败代码}void main(){   int a,b,d = 0;   cout<<"############迷宫算法############"<<endel;   cout<<"迷宫初始化状态是:"<<endl;   cout<<" 0 1 2 3 4 5 6 7 8 9"<<endl;   for(a=0;a<8;a++)//输出显示迷宫初始状态   {      cout<<a; for(b = 0;b <10; b++) {    if(maze[a][b] = 1)cout<<"  "<<" #";elsecout<<"  ";//cout<<"  "<<maze[a][b]; } cout<<endl;   }   int startX,startY,endX,endY;   cout<<"请输入出发点坐标x,y"<<endl;   cin>>startX>>startY;   cout<<"请输入终点坐标x,y"<<endl;   cin>>endX>>endY;   LinkedStack<Point> *s= new LinkedStack<Point>;       int result = path(s,maze,startX,startY,endX,endY);  cout<<" 遍历过的路径,从开始:"<<endl;  cout<<" 0 1 2 3 4 5 6 7 8 9"<<endl;  for(a=0;a<8;a++)//输出迷宫走过的路径,从起点开始增加  {  cout<<a;  for(b = 0;b<10;b++)  {    if(maze[a][b]>=10){   cout<<" "<<maze[a][b];}else cout<<"  "<<maze[a][b];  }  cout<<endl;}   if(result){      Point temp;  while(!s->isEmpty ())  {     temp = s->pop (); maze[temp.x][temp.y] = 50+temp.d ;//栈中坐标点的方向加  }  cout<<"标记出路为:"<<'\n'<<" 注:->标记路线"<<endl;  cout<<"  0 1 2 3 4 5 6 7 8 9" <<endl;  for(a = 0; a < 8;a++) //输出迷宫开始到终点的路线  {   cout<<a;  for(b = 0;b<10;b++)  {     if(maze[a][b] == 1) cout<<"  "<<maze[a][b]; else {    switch (maze[a][b]){case 50: cout<<"→";d = 4; break;case 51: cout<<"↓";d = 4; break;case 52: cout<<"←";d = 4; break;case 53: cout<<"↑";d = 4; break;default: cout<<"   ";} }  }  cout<<endl;  }  }  else  cout<<" 不能到达!"<<endl;}


0 0
原创粉丝点击