/************************************************************************************************
栈:是一种仅限在表尾进行插入和删除操作的线性表,又称为后进先出的线性表 LIFO (Last In First Out)
允许插入和删除的一端称为栈顶(top),另外一端称之为栈底(bottom)
不含任何数据元素的栈称之为空站。
栈是一种线性表,也就是说栈具有线性关系即前驱后继关系。只不过是一种特殊的线性表而已。
其特殊之处就是在于限定了线性表的插入和删除的位置,它始终只能在栈顶进行操作。
栈的插入:进栈,入栈,压栈; 栈的删除:出栈,弹栈;
栈的顺序存储相对比较方便,只准栈顶进出元素,不存在线性表插入和删除时需要移动大量元素的问题;
但是有个缺陷,就是必须要实线确定数组存储空间的大小,万一不够用,就需要用编程手法来扩展数组容量。
************************************************************************************************/
#define MAXSIZE 20 //存储空间初始分配量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
/**************************************栈的顺序存储结构********************************************
定义一个变量top来指示栈顶元素在数组中的位置,若栈的长度为StackSize,则栈顶位置top必须小于StackSize.
当存在一个元素时,top等于0,因此对于空栈的判定条件为top == -1
************************************************************************************************/
typedef int SElemType; //SElemType 数据类型
typedef int Status;
typedef struct
{
SElemType data[MAXSIZE];
int top; //用于栈顶指针
}SqStack;
// 入栈操作 O(1)
Status Push(SqStack *S, SElemType e)
{
if(S->top == MAXSIZE -1) //判断栈满
return ERROR;
S->top ++; //栈顶指针增加
S->data[S->top] = e; //将新的元素插入栈顶空间
return OK;
}
// 出栈操作 O(1)
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;
极端情况,如果栈2为空栈,栈1的top1等于n-1,则栈1为满;反之,栈1的top1为空时,top2等于0时,栈2满。
但是这种情况相对较少,更多情况是两栈在中间某处相见,也就是说,当两栈的指针之差为1时,及top1+1 = top2时,
则整个栈为满栈。
************************************************************************************************/
typedef struct
{
SElemType data[MAXSIZE];
int top1;
int top2;
}SqDoubleStack;
// 插入时,需要提供相应的栈号
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;
else if(stackNumber == 2) //栈2有元素进栈
s->data[-- s->top2] = e;
return OK;
}
// 删除元素
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并且返回OK,否则返回ERROR*/
Status Pop(SqDoubleStack *s, SElemType *e, int stackNumber)
{
if(stackNumber == 1) //由于栈1,2栈空条件不一样,区分对待
{
if(s->top1 == -1)
return ERROR; //栈1空,下溢出
*e = s->data[s->top1 --]; //栈1的栈顶元素出栈
}
else if(stackNumber == 2)
{
if(s->top2 == MAXSIZE)
return ERROR; //栈2空,下溢出
*e = s->data[s->top2 ++]; //栈2的栈顶元素出栈
}
return OK;
}