栈(Stack)是只允许在一端进行插入或删除操作的线性表。
特点:先进后出。
逻辑结构:与普通线性表相同。
数据运算:插入、删除操作有区别。
一、操作
InitStack(&S):初始化栈。构造一个空栈 S,分配内存空间。
DestroyStack(&S):销毁栈。销毁并释放栈 S 所占用的内存空间。
Push(&S,x):进栈,若栈 S 未满,则将 x 加入使之称为新栈顶。
Pop(&S,x):出栈,若栈 S 非空,则弹出栈顶元素,并用 x 返回。
GetTop(S,&x):读栈顶元素。若栈 S 非空,则用 x 返回栈顶元素。
StackEmpty(S):判断一个栈 S 是否为空。若 S 为空,则返回 0,不为空返回 1。
二、栈的顺序存储实现
1、栈数据类型
#define MAXSIZE 10 // 定义最大长度
typedef int ElemType; // 根据实际情况定义
typedef struct{
ElemType data[MAXSIZE]; // 用数组存放数据元素(ElemType - 实际数据类型)
int top; // 栈顶指针
}StackT; // Stack(列表)T(数据类型)Q(指针类型)
2、操作
void initStack(StackT *s); // 初始化栈
int statckEmpty(StackT *s); // 栈空判断
int push(StackT *s,ElemType x); // 入栈
int pop(StackT *s,ElemType *x); // 出栈
int getTop(StackT *s,ElemType *x); // 读栈顶元素
1、InitStack(&S)
/****************************************
* 初始化栈
* s - 要操作的栈首地址
****************************************/
void initStack(StackT *s)
{
s->top = -1;
for(int i=0;i<MAXSIZE;i++){
s->data[i] = 0;
}
}
2、DestroyStack(&S)
以静态存储方式实现栈,无法进行销毁。
3、Push(&S,x)
/****************************************
* 入栈
* s - 要操作的栈首地址
* x - 栈顶插入元素
****************************************/
int push(StackT *s,ElemType x)
{
if(s->top==MAXSIZE-1) return 1; // 栈满
s->top = s->top + 1; // 栈顶指针移动
s->data[s->top] = x; // 新元素入栈
// s->data[++s->top] = x; // 此语句等价于以上 2 行
return 0;
}
4、Pop(&S,x)
/****************************************
* 出栈
* s - 要操作的栈首地址
* x - 用于存放栈顶元素
* 注:栈顶元素只是在逻辑上被删除(实际元素还残留在内存中)
****************************************/
int pop(StackT *s,ElemType *x)
{
if(s->top==-1) return 1; // 栈空
*x = s->data[s->top]; // 栈顶指针元素出栈
s->top = s->top-1; // 移动栈顶指针
// *x = s->data[s->top--]; // 此语句等价于以上 2 行
return 0;
}
5、GetTop(S,&x)
/****************************************
* 读栈顶元素
* s - 要操作的栈首地址
* x - 用于存放栈顶元素
* 注:和出栈类似
****************************************/
int getTop(StackT *s,ElemType *x)
{
if(s->top==-1) return 1; // 栈空
*x = s->data[s->top]; // 读取栈顶元素
return 0;
}
6、StackEmpty(S)
/****************************************
* 判断栈空
* s - 要操作的栈首地址
****************************************/
int statckEmpty(StackT *s)
{
if(s->top == -1) return 0;
else return 1;
}
三、共享栈
栈满判断条件:top0 + 1 == top1
四、栈的链式存储实现
1、除 Push、Pop 外其他操作和单链表相同。
2、Push 操作使用单链表的头插法。
3、Pop 操作使用单链表的头删法。
栈的实现使用不带头结点的单链表更方便。