栈(stack)是限定仅在表尾进行插入或删除操作的线性表。栈实现了一种先进后出(last-in, fast-out, 缩写为LIFO)的策略。形象的比喻:生活中的放盘子,最先放的盘子在最下面,最后放的盘子在上面。
栈的实现
#define STACK_INIT_SIZE 100u
#define STACKINCREMENT 10u
定义结构体SElemType
typedef struct {
int val;
}SElemType;
定义结构体SqStack.
typedef struct {
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
- base指向栈底。
- top指向栈顶。
- stacksize指示栈的当前可使用的最大容量。
当base值为NULL,表明栈结构不存在。当base=top,表明栈为空。
构造空栈
void InitStack(SqStack *S)
{
S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (S->base == NULL)
{
exit(0);
}
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
}
销毁栈
void DestroyStack(SqStack *S)
{
free(S->base);
S->base = S->top = NULL;
S->stacksize = 0;
}
清空栈
void ClearStack(SqStack *S)
{
S->top = S->base;
}
空栈检测
int StackEmpty(SqStack *S)
{
int tmp = 0;
if (S->base == S->top)
{
tmp = 1;
}
else
{
tmp = 0;
}
return tmp;
}
栈的长度
int StackLength(SqStack *S)
{
return (int)(S->top - S->base);
}
获取栈顶
void GetTop(SqStack *S, SElemType *e)
{
if (S->top == S->base)
{
exit(0);
}
else
{
*e = *(S->top - 1);
}
}
入栈
void Push(SqStack *S, SElemType *e)
{
if (S == NULL)
{
exit(0);
}
if (S->top - S->base >= S->stacksize)
{
S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S->base)
{
exit(0);
}
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*(S->top++) = *e;
}
出栈
SElemType Pop(SqStack *S)
{
if (S->top == S->base)
{
exit(0);
}
return *(--S->top);
}
栈的遍历
void StackTraversal(SqStack *S, void (*fp)(SElemType))
{
SElemType *tmp = S->base;
while (tmp < S->top)
{
(*fp)(*tmp);
tmp++;
}
}
栈的操作的序列是直线式的,即先一味地入栈,然后一味地出栈。为什么这一过程不直接用数组实现?当然数组是定长的缺点不是一个确切的答案。这个问题还可以扩展到队列、链表。