定义
栈是仅限定在表尾进行插入和删除操作的线性表。
我们把允许插入和删除的一段称为栈顶,另一端称为栈底,不包含任何数据元素的称为空栈。栈又称为后进先出的线性表。简称为LIFO结构。
栈的抽象数据类型
ADT 栈(stack)
Data
同线性表。元素具有相同的类型。相邻元素具有前驱和后继关系
Operation
InitStack(*S) :初始化操作,建立一个空栈
DestroyStack(*S): 若栈存在,则销毁它
ClearStack(*S): 将栈清空
StackEmpty(S):若栈为空,返回true,否则返回false
GetTop(S,*e):若栈存在且非空,用e返回S的栈顶元素
Push(*S,e):若栈S存在,插入新元素e到栈S中并成为栈顶元素。
Pop(*S,*e):删除栈S中栈顶元素,并用e返回其值。
StackLength(S):返回栈S的元素个数
栈的顺序存储结构
1.结构定义
用数组来存储:下标为0作为栈底,用变量top来指示栈顶元素在数组中的位置
(C语言)
#define MAXSIZE 50
#define OK 1
#define ERROR 0
#define True 1
#define False 0
typedef int Status;/*函数的返回类型,这里定义为int*/
typedef int SElemType;/*SElemType根据情况来顶,这里假设为int*/
typedef struct
{
SElemType data[MAXSIZE];
int top; /*用于栈顶指针*/
}SqStack;
2.进栈操作
/*插入元素e为新的栈顶元素*/
Status Push(SqStack *S,SElemType e)
{
if(S->top==MAXSIZE-1) //栈满
{
return ERROR;
}
S->top++; //栈顶指针加1
S->data[S->top]=e;
return OK;
}
3.出栈操作
/*若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR*/
Status Pop(SqStack *S,SElemType *e)
{
if(S->top==-1)
{
return ERROR;
}
*e=S->data[S->top];
S->top--;
return OK;
}
两栈共享空间
为了克服顺序存储时,栈的存储空间必须事先确定这一缺点,我们可以利用共享栈。
共享栈,就是数组有两个端点,两个栈有两个栈底,让一个栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下端为数组长度n-1处。这样,两个栈如果增加元素,就是两端点向中间延伸。
定义top1和top2是栈1和栈2的栈顶指针
栈满的情况:
top1为空栈 ,top2指向0时,栈2满
top2为空栈,top1指向n-1时,栈1满
当top1+1=top2时,栈满
两栈共享空间的结构的代码如下:
/*两栈共享空间结构*/
typedef struct
{
SElemType data[MAXSIZE];
int top1; //栈1栈顶指针
int top2; //栈2栈顶指针
}SqDoubleStack;
入栈操作:
Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
if(S->top1+1==S->top2) //栈已满,不能再push新元素了
{
return ERROR;
}
if(stackNumber==1) //向栈1插入元素
{
S->data[++S->top1]=e;
}
else if(stackNumber==2) //向栈2插入元素
{
S->data[--S->top2]=e;
}
return OK;
}
出栈操作:
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{
if(stackNumber==1)
{
if(S->top1==-1) //栈1已空,无法弹出
{
return ERROR;
}
*e=S->data[S->top1--];
}
if(stackNumber==2)
{
if(S->top2==MAXSIZE) //栈2已空,无法弹出
{
return ERROR;
}
*e=S->data[S->top2++];
}
return OK;
}
栈的链式存储结构
链栈的结构代码:
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStackPtr;
typedef struct LinkStack
{
LinkStackPtr top;
int count;
}LinkStack;
进栈代码:
Status Push(LinkStack *S,SElemType e)
{
LinkStackPtr s=(LinkStackPtr)malloc(sizeof (StackNode));
s->data=e;
s->next=S->top; //把当前的栈顶元素赋值给新节点的直接后继
S->top=s; /*将新的节点s赋值给栈顶指针*/
S->count++;
return OK;
}
出栈代码:
Status Pop(LinkStack *S,SElemType *e)
{
LinkStackPtr p;
if(StackEmpty(*S))
{
return ERROR;
}
*e=S->top->data;
p=S->top; /*将栈顶节点赋值给p*/
S->top=S->top->next; /*使栈顶指针后移一位,指向后一节点*/
free(p); /*释放节点p*/
S->count--;
return OK;
}
栈的应用
- 递归
- 四则运算表达式求值
栈的C++实现
#include <iostream>
using namespace std;
template<typename T>
class Stack
{
public:
Stack(int s=10);
~Stack();
bool StackEmpty();
int StackLength();
T GetTop(T &e);
void Push(T e);
T Pop(T &e);
private:
T *base;
T *top;
int stacksize,count;
T *array;
};
template<typename T>
Stack<T>::Stack(int s)
{
array=new T[s];
stacksize=s;
count=0;
top=base=array;
}
template<typename T>
Stack<T>::~Stack<T>()
{
}
template<typename T>
int Stack<T>::StackLength()
{
return count;
}
template<typename T>
bool Stack<T>::StackEmpty()
{
return count==0;
}
template<typename T>
T Stack<T>::GetTop(T &e)
{
e=*(top-1);
return e;
}
template<typename T>
void Stack<T>::Push(T e)
{
if(count+1<=stacksize)
{
count++;
*top=e;
top++;
}
else
{
cout<<"栈空间不足"<<endl;
}
}
template<typename T>
T Stack<T>::Pop(T &e)
{
if(count==0)
{
cout<<"栈已空,无法弹出"<<endl;
}
else
{
e=*(top-1);
top--;
count--;
}
return e;
}
int main()
{
Stack<int> a1(9);
for(int i=0;i<9;i++)
{
a1.Push(i);
}
cout<<"栈的大小:"<<a1.StackLength()<<endl;
cout<<"栈是否为空:"<<a1.StackEmpty()<<endl;
int e;
cout<<"栈顶元素:"<<a1.GetTop(e)<<endl;
while (!a1.StackEmpty())
{
int e;
cout<<a1.Pop(e)<<endl;
}
system("pause");
return 0;
}