1. 基本概念
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表。表头称为栈底,表尾称为栈顶,不含元素的空栈叫做空栈。栈具有后进先出(LIFO)的特点。
2. 抽象数据类型(ADT)
数据对象:{a1, a2, ..., an},每个元素类型为 DataType,与线性表类似。
数据关系:除第一个元素外,每一个元素有且只有一个直接前驱元素;除最后一个元素外,每个元素有且只有一个直接后驱。一对一的对应关系。第一个元素被称为栈底元素,最后一个元素为栈顶元素。
基本操作包括:
- InitStack(*S): 建立一个空栈。
- DestroyStack(*S): 若栈存在,则销毁它。
- ClearStack(*S): 将栈清空。
- StackEmpty(S): 若为空,返回 true,否则返回 false。
- GetTop(S, *e): 若栈存在且非空,则返回栈顶元素值给 e。
- Push(*S, e): 插入 e 为栈顶元素。
- Pop(*S, *e): 删除栈顶元素,并将值返回给 e。
- StackLength(S): 返回栈 S 的元素个数。
3. 顺序存储实现
顺序栈利用一段连续的存储空间来存放数据,通过指针移动来模拟栈的操作。下面是一个基于 C 语言的完整实现,包含了初始化、扩容、入栈、出栈等核心逻辑。
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
#include <stdlib.h>
#include <stdio.h>
// 栈的顺序存储结构定义
#define STACK_INIT_SIZE 100 // 栈的初始存储空间容量
#define STACKINCREMENT 10 // 当栈满时,每次新增的存储空间增量
typedef int ElemType; // 元素的数据类型根据实际情况而定,这里假设为 int
typedef struct Stack {
ElemType *base; // 栈底指针,始终指向栈底,当指向 NULL 时,则栈结构不存在
ElemType *top; // 栈顶指针,指向栈顶元素的下一个元素,当栈为空时,栈顶指针指向栈底
int stacksize; // 当前栈的存储空间容量
} SqStack;
int InitStack
{
(!(S->base = (ElemType*)(STACK_INIT_SIZE * (ElemType)))) ERROR;
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
OK;
}
{
(S->base) {
S->stacksize = ;
(S->base);
S->base = ;
S->top = ;
}
OK;
}
{
(S->base != S->top) {
S->top--;
}
OK;
}
{
(S.base == S.top) TRUE;
FALSE;
}
{
(S.base == S.top) ERROR;
*e = *(S.top - );
OK;
}
{
((S->top - S->base) >= S->stacksize) {
S->stacksize += STACKINCREMENT;
(!(S->base = (ElemType*)(S->base, S->stacksize * (ElemType)))) ERROR;
}
*(S->top) = e;
S->top++;
OK;
}
{
(S->base == S->top) ERROR;
*e = *(--S->top);
OK;
}
{
(S.top - S.base);
}
{
SqStack S;
e, choice;
{
();
(, &choice);
(choice) {
: {
e = StackLength(S);
(, e);
;
}
: {
();
(, &e);
Push(&S, e);
;
}
: {
POP(&S, &e);
(, e);
;
}
: {
GetTop(S, &e);
(, e);
;
}
: {
(, StackEmpty(S));
;
}
: {
ClearStack(&S);
;
}
: {
InitStack(&S);
;
}
: {
DestroyStack(&S);
;
}
}
} (choice != );
;
}

