棧(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++;
}
}
棧的操作的序列是直線式的,即先一味地入棧,然後一味地出棧。爲什麼這一過程不直接用數組實現?當然數組是定長的缺點不是一個確切的答案。這個問題還可以擴展到隊列、鏈表。