栈的类型定义:栈是一种特殊的线性表,限定只能在表的一端进行插入和删除操作的线性表。在表中,允许插入删除的一端称为“栈顶”,不允许插入删除的另一端称为“栈底”,没有元素的栈称为空栈,插入元素称为入栈,删除元素称为出栈,称为先进后出。
顺序栈类型的定义:顺序栈的存储方式是数组,需要事先为他分配一个可容纳最多元素的存储空间,“栈顶指针”意为指示栈顶元素在栈中的位置,在栈的长度已知的情况下,这个值也实际上反应了栈中元素的个数,和顺序表中的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;
else
d = 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<<" "<<" #";
else
cout<<" ";//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;
}