栈(stack)
定义
栈是限定仅在表尾进行插入和删除操作的线性表
- 允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
- 后进先出(Last In First Out),LIFO结构
抽象数据类型
ADT 栈(stack)
Data
同线性表
Operation
InitStack(*S) //初始化
DestoryStack(*S) //销毁
ClearStack(*S) //清空
StackEmpty(S) //判断是否为空
GetTop(S,*e) //用e返回栈顶元素
Push(*S,e) //压栈
Pop(*S,*e) //出栈
StackLength(S) //元素个数
endADT
顺序存储结构
- 当栈存在一个元素时,top等于0,所以一般把空栈的判定条件定为top等于-1
typedef int SElemType;
typedef struct
{
SElemType data[MAXSIZE];
int top;
}SqStack;
/*进栈*/
Status Push(SqStack *S, SElemType e)
{
if(S->top == MAXSIZE - 1) /*栈满*/
return ERROR;
S->top++; /*栈顶指针加一*/
S->data[S->top] = e; /*赋值*/
return OK;
}
/*出栈*/
Status Pop(SqStack *S, SElemType *e)
{
if(S->top == -1) /*栈空*/
return ERROR;
*e = S->data[S->top];
S->top--;
return OK;
}
双栈共享空间
-
两个相同数据类型的栈
-
栈1为空时,
top1 == -1
,栈2为空时,top2 == n
-
栈满时想极端情况,
top1==n-1
或top2==0
,即top1+1==top2
或top2-1==top1
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) /*栈满*/
return ERROR;
if(stackNumber == 1)
S->data[++S->top1] == e;
else if (stackNumber == 2)
S->data[--S->top1] == e;
return OK;
}
/*出栈*/
Status Pop(SqDoubleStack *S, SElemType *e, int stackNumber)
{
if(stackNumber == 1)
{
if(S->top1 == -1)
return ERROR;
*e = S->data[S->top1--];
}
else if (stackNumber == 2)
{
if(S->top2 == MAXSIZE)
return ERROR;
*e = S->data[S->top2++];
}
return OK;
}
链式存储结构(链栈)
- 单链表有头指针,栈顶指针也是必须的,所以方便起见就把栈顶放在单链表的头部,因为栈顶放在头部,单链表常用的头结点也没意义了,对链栈来说就不需要头结点了
- 基本不存在栈满的情况
- 链栈的空top=NULL
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->count++;
return OK;
}
/*出栈*/
Status Pop(LinkStack *S, SElemType *e)
{
LinkStackPtr p;
if(StackEmpty(*S))
return ERROR;
p = S->top;
*e = p->data;
S->top = p->next;
free(p);
S->count--;
return OK;
}
四则运算
后缀(逆波兰)表示法
不需要括号的后缀表达法
计算机处理过程:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号就将处于栈顶的两个数字出栈,运算结果进栈,最终获得结果
9 3 1 - 3 * + 10 2 / +
答案20,自己推一遍
中缀表达式转后缀表达式
标准四则运算表达式是中缀表达式