3.1 栈
3.1.1 栈的基本概念
-
栈(stack):栈是只允许在一端进行插入和删除操作的线性表
-
栈顶:线性表允许进行插入和删除的一端
-
栈底:固定的,不允许进行处插入和删除的另一端
-
空栈:不含任何元素的空表
-
栈的数学性质:n个不同元素进栈,出栈元素不同排列的个数为 1 n + 1 C 2 n n \frac{1}{n+1}C_{2n}^{n} n+11C2nn(卡特兰数)
-
栈的特性:后进先出(LIFO)
-
栈的基本操作:
- InitStack(&S):初始化一个空栈S
- DestroyStack(&S):销毁栈,并释放S占用的存储空间
- StackEmpty(S):判断一个栈是否为空
- Push(&S, x):进栈,若栈未满,则将x加入成为新栈顶
- Pop(&S, &x):出栈,若栈S非空,则弹出栈顶元素,并用x返回
- GetTop(S, &x):读栈顶元素,若栈S非空,则用x返回栈顶元素
3.2 栈的存储结构
3.2.1 顺序栈的实现
-
顺序栈的实现:采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储空间存放自栈顶到栈底的数据元素,同时附设一个指针(top)指示当前栈顶元素
-
栈的顺序存储类似
#define MaxSize 50 typedef struct{ ElemType data[MaxSize]; int top; }SqStack;
- 栈顶指针:S.top,初始化时S.top=-1;
- 栈顶元素:S.data[S.top]
- 进栈:栈不满时,先让栈指针+1,再送值去栈顶
- 出栈:栈非空时,先取出栈顶元素值,再让栈顶指针-1
- 栈空条件:S.top==-1
- 栈满条件:S.top==MaxSize-1
- 栈长:S.top+1
如果top=0表示栈空,则说明top指向栈顶元素的下一个存储单元
3.2.2 顺序栈的基本运算
-
初始化
void InitStack(SqStack &S){ S.top=-1; }
-
判栈空
bool StackEmpty(SqStack S){ if(S.top==-1) return true; else return false; }
-
进栈
bool Push(Sqstack &S, ElemType x){ if(S.top==MaxSize-1) return false; /* * 若栈空条件为S.top=0的情况 * if(S.top==MaxSize) return false; * S.data[top++]=x */ S.data[++S.top] = x; return true; }
-
出栈
bool Pop(SqStack &S, ElemType &x){ if(S.top==-1) return false; /* * 若栈空条件为S.top=0的情况 * x=S.data[--top] */ x=S.data[S.top--]; return true; }
-
读取栈顶元素
bool GetTop(SqStack S, ElemType &x){ if(S.top==-1) return false; x=S.data[S.top]; return true; }
3.2.3 共享栈
-
共享栈:让两个顺序栈共享一个一维数组空间(这个数组就是共享栈)
-
原理:利用栈底的相对不变的特性,将两个栈的栈底分别设置在共享栈的两端,两个栈顶向共享空间的中间延伸
- top0=-1时表示0号栈为空,top1=MaxSize时表示1号栈为空
- 当top1-top0==1时表示共享栈满了
- 进栈操作:top0先+1再进栈,top1先-1再进栈,出栈相反
-
目的:更有效利用存储空间,两个栈的空间互相调节,只有整个存储空间满了才发生上溢
3.3.4 栈的链式存储
-
链栈:采用链式存储的栈称为链栈
-
优点:便于多个栈共享存储空间和提高效率,不存在栈满上溢
-
栈的链式存储类型描述
/*一般没有头结点,操作在表头进行*/ typedef struct LinkNode{ ElemType data; struct LinkNode *next; }LiNode, *LiStack;
-
初始化
void InitLiStack(LiStack &S){ S=NULL; int x; scanf("%d", &x); while(x!=9999){ LiStack* node=(LiNode*)malloc(sizeof(LiNode)); node.data=x; node->next=S; S=node; scanf("%d", &x); } }
-
进栈
bool Push(ListStack &S, LiNode e){ if(!e) return false; e->next=S; S=e; }
-
出栈
bool Pop(ListStack &S, LiNode &e){ if(!S) return false; e=S; S=S->next;c }
-
栈顶元素
bool GetTop(ListStack S, LiNode &e){ if(!S) return false; e=S;c return true; }
-
判空
bool StackEmpty(ListStack S){ if(!S) return true; else return false }