栈是限定仅在表尾进行插入或删除的线性表。对栈来说,表尾端有其特殊含义,称为栈顶,相应的,表头端称为栈底,不含元素的空表称为空栈。栈又称为后进先出的线性表。因为和线性表类似,所以栈有两种存储表示方法,分别称为顺序栈和链栈。
#define MAXSIZE 100 //栈顺序存储空间的初始分配量
typedef struct
{
SElemType *base; //栈底指针
SElemtype *top; //栈顶指针
int stacksize; //栈可用的最大容量
}sqStack;
顺序栈的初始化操作就是为顺序栈动态分配一个预定义大小的数组空间。
1.为顺序栈动态分配一个最大容量为 MAXSIZE 的数组空间,是 base 指向这段空间的基地址,即栈底。
2.栈顶指针 top 初始为 base, 表示栈为空。
3.stacksize 置为栈的最大容量 MAXSIZE。
Status InitStack(sqStack &S)
{
//构造一个空栈S
S.base = new SElemType[MAXSIZE]; //为顺序栈动态分配一个最大容量为MAXSIZE的数组空间
if(!S.base) exit(OVERFLOW); //存储分配失败
S.top = S.base; //top初始为base,空栈
S.stacksize = MAXSIZE; //stacksize置为栈的最大容量MAXSIZE
return OK;
}
入栈操作就是指在栈顶插入一个新的元素。
1.判断是否栈满,若满返回ERROR。
2.将新元素压入栈顶,栈顶指针加 1。
Status Push(sqStack &S, SElemtype e)
{
//插入元素e为新的栈顶元素
if(S.top - S.base == S.stacksize ) return ERROR; //栈满
*S.top ++ = e; //元素e压入栈顶,栈顶指针加 1
return OK;
}
出栈操作就是将栈顶元素删除。
1.判断是否栈空,若空则返回ERROR。
2.栈顶指针减 1,栈顶元素出栈。
Status Pop(sqStack &S, SElemType &e)
{
//删除S的栈顶元素,用e返回其值
if(S.top == S.base) return ERROR; //栈空
e = *--S.top; //栈顶指针加 1,将栈顶元素赋给e
return OK;
}
当栈非空时,此操作返回当前栈顶元素的值,栈顶指针保持不变。
SElemType GetTop(sqStack S)
{
//返回S的栈顶元素,不修改栈顶指针
if(S.top != S.base) //栈非空
return *(S.top - 1); //返回栈顶元素的值,栈顶指针不变
}
因为顺序栈收到最大空间容量大限制,所以在无法预先知道栈可能达到的最大容量时,我们应该使用链栈。
typedef struct StackNode
{
ElemType date; //栈底指针
struct StackNode *next;
}StackNode, *LinkStack;
链栈的初始化操作就是构造一个空栈,因为没有必要设头结点,所以直接将栈顶指针置空即可。
Status InitStack(LinkStack &S)
{
//构造一个空栈S ,栈顶指针置空
S = NULL;
return OK;
}
和顺序栈的入栈操作不同的是,链栈在入栈前不需要判断是否栈满,只需要为入栈元素动态分配一个结点空间。
1.为入栈元素 e 分配空间,用指针 p 指向。
2.将新结点数据元素域置为 e 。
3.将新结点插入栈顶。
4.修改栈顶指针为 p。
Status Push(LinkStack &S, SElemtype e)
{
//插入元素e为新的栈顶元素
p = new StackNode; //生成新的结点
p->data = e; //将新结点数据域置为e
p->next = S; //将新结点插入栈顶
S = p; //修改栈顶指针为p
return OK;
}
和顺序栈一样,链栈在出栈前也需要判断栈是否为空,不同的是,链栈在出栈后需要释放出栈元素的栈顶空间。
1.判断栈是否为空,若空则返回RRROR。
2.将栈顶元素赋给 e 。
3.临时保存栈顶元素的空间,以备释放。
4.修改栈顶指针,指向新的栈顶元素。
5.释放原栈顶元素的空间。
Status Pop(LinkStack &S, SElemtype &e)
{
//删除S的栈顶元素,用e返回其值
if(S == NULL) return ERROR; //栈空
e = S->date; //将栈顶元素赋给 e
p = S; //用p临时保存栈顶元素空间,以备释放
S = S->next; //修改栈顶指针
delete p; //释放原栈顶元素的空间
return OK;
}
与顺序栈一样,当栈非空时,此操作返回当前栈顶元素的值,栈顶指针 S 保持不变。
SElemType GetTop(LinkStack S)
{
//返回S的栈顶元素,不修改栈顶指针
if(S != NULL) //栈非空
return S->date ; //返回栈顶元素的值,栈顶指针不变
}
文章借鉴:《数据结构》(C语言版)(第二版)人民邮电出版社