栈是限定仅在表尾进行插入和删除的线性表。
允许插入和删除的一端叫栈顶,另一端叫栈底。不含有任何数据元素的栈叫空栈。栈又称为后进先出的线性表。简称LIFO结构。
//栈的抽象数据类型
ADT 栈(stack)
Data
同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。
Operation
InitStack(*S):初始化操作,建立一个空栈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的元素个数。
endADT
//栈的结构定义
typedef int SElemType; //SElemType类型根据实际情况而定。
typedef struct
{
SElemType data[MAXSIZE];
int top; //用于栈顶指针
}SqStack;
//插入元素e为新的栈顶元素
Status Push(SqStack *S,SElemType e)
{
if(S->top == MAXSIZE - 1) //栈满
{
return ERROR;
}
S->top++; //栈顶指针增加一
S->data[S->top] = e; //将新插入元素赋值给栈顶空间
return OK;
}
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR
Status Pop(SqStack *s,SElemType *e)
{
if(S->top == -1)
return ERROR;
*e = S->data[S->top]; //将要删除的栈顶元素赋值给e
S->top--; //栈顶指针减一
return OK;
}
//两栈共享空间的结构
typedef struct
{
SElemType data[MAXSIZE];
int top1;
int top2;
}SqDoubleStack;
//插入元素e为新的栈顶元素
Status Push(SqDoubleStack *s,SElemType e,int stackNumber)
{
if(S->top1 + 1 == S->top2) //栈满
return ERROR;
if(stackNumber == 1) //栈1 有元素
S->data[++S->top1] = e; //top1先加一后给数组元素赋值
else if(stackNumber == 2) //栈2有元素
S->data[--S->top2] = e; //栈2的top2-1后给数组元素赋值
return OK;
}
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{
if(stackNumber == 1)
{
if(S->top1 == -1)
return ERROR; //栈1 为空,
*e = S->data[S->top1--];//栈1的栈顶元素出栈
}
else if(stackNumber = MAXSIZE)
{
if(S->top2 == MAXSIZE)
return ERROR; //栈2为空
*e = S->data[S->top2++]; //将栈2的栈顶元素出栈
}
return OK;
}
栈的链式存储结构简称为链栈。
//链栈数据结构
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStackPtr;
typedef struct LinkStack
{
LinkStackPtr top;
int count;
}LinkStack;
//插入元素e为新的栈顶元素
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;
}
//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR
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); //释放栈顶结点
S->count--;
return OK;
}
把直接调用自己或通过一系列的调用语句间接的调用自己的函数称为递归函数。