栈的存储结构定义
/*顺序栈结构*/
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;
}
相关变量定义
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /*存储空间初始分配量*/
typedef int Status;
typedef int SElemType;/*SElemType 类型根据实际情况而定,这里假设为int*/
两栈共享空间
如图,数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为 0 处 ,另一个栈为栈的末端,即下标为数组长度n-1处。这样,两个栈如果增加元素,就是两端点向中间延伸。
其实关键思路是:它们是在数组的两端,向中间靠拢。top1 和 top2 是栈1和栈2的栈顶指针,可以想象,只要它们俩不见面,两个栈就可以一直使用。从这里也就可以分析出来,栈 1 为空时,就是 top1 等于-1 时;而当 top2 等于n 时,即是栈 2 为空时,那什么时候栈满呢?想想极端的情况,若栈2是空栈,栈1的 topl 等于 n-1时,就是栈1满了 。 反之,当栈 1为空栈时, top2 等于0时,为栈 2 满。 但更多的情况,其实就是我刚才说的,两个栈见面之时,也就是两个指针之间相差 1时,即 top1+1= top2 为栈满。
存储结构:
/*两栈共享空间*/
typedef struct
{
SElemType data[MAXSIZE];
int top1; /*栈1栈顶指针*/
int top2; /*栈2栈顶指针*/
}SqDoubleStack;
插入操作:
/*插入元素e为新的栈顶元素*/
Status PushD(SqDoubleStack *S, SElemType e, int stackNumber)
{
if (S->top1 + 1 == S->top2)
return ERROR;
if (stackNumber == 1) /*栈1元素进栈*/
{
S->data[++S->top1] = e;/*若栈1则先top1+1后给数组元素赋值*/
}
else if (stackNumber==2) /*栈2元素进栈*/
{
S->data[--S->top2] = e;/*若栈2则先top2+1后给数组元素赋值*/
}
return OK;
}
出栈操作:
Status PopD(SqDoubleStack *S, SElemType *e, int stackNumber)
{
if (stackNumber == 1)
{
if (S->top1 == -1) /*说明栈1已经是空栈,溢出*/
return ERROR;
*e = S->data[S->top1--];/*将栈1的栈顶元素出栈,再移动top指针*/
}
else if (stackNumber == 2)
{
if (S->top2 == MAXSIZE)/*说明栈2已经是空栈,溢出*/
return ERROR;
*e = S->data[S->top2++];/*将栈2的栈顶元素出栈,再移动top指针*/
}
return OK;
}