目录
1 顺序栈的定义
- 数据结构中的栈(Stack)是一种特殊的线性表,其特殊性在于它只能在一端进行插入和删除操作,这一端被称为栈顶,另一端则被称为栈底。栈遵循“后进先出”(Last In First Out,LIFO)的原则,即最后一个被放入栈中的元素总是第一个被取出。
- 在编程中,栈常用于实现函数调用、表达式求值、数制转换、迷宫求解等算法。例如,在函数调用中,每调用一个函数,就将该函数的局部变量和返回地址压入调用栈中,当函数返回时,再从调用栈中弹出相应的数据。这种机制确保了函数调用的正确性和顺序性。
名词解释:
- 栈顶:允许插入删除的一端。
- 栈底:不允许插入删除的一端。
- 空栈:不包含任何元素的空表。
#define MaxSize 50
typedef struct{
ElemType data[MaxSize];
int top;
}Stack;
2 顺序栈的基本操作
2.1 初始化:
void InitStack(Stack &S){
S.top=-1;
}
2.2 判空栈
#define true 1
#define false 0
bool EmptyStack(Stack S){
if(S.top==-1) return true;
else return false;
}
2.3 进栈
首先,判断是否栈满。如栈满,则退出程序。若未满,则先让top指针加一,在进行入栈操作。
bool Push(Stack &S,ElemType e){
if(S.top==MaxSize-1) return false; //栈满?
S.data[++S.top]=e;
return true;
}
2.4 出栈
首先,判断是否栈空。若空,则退出程序。反之,则让e等于出栈元素,再让top指针减1。
bool Pop(Stack &S,ElemType &e){
if(S.top==-1) return false; #判栈空
e=S.data[S.top--];
return true;
}
2.5 读栈顶元素
bool GetTop(Stack S,ElemType &e){
if(S.top==-1) return false; //判栈空
e=S.data[S.top];
return true;
}
读栈顶元素与出栈类似,只是读并没有将元素出栈。
注意:
在本节定义中,栈的初始化是将S.top初始为-1。但是,S.top也可以初始为0。
当初始化S.top==0时,
进栈操作的代码:S.data[++S.top]=e;
应改为:S.data[S.top++]=e;
出栈操作的代码:e=S.data[S.top--];
应该为:e=S.data[--S.top];
3 共享栈
3.1 共享栈的实现
#define MaxSize 50
typedef struct{
ElemType data[MaxSize];
int top1=0;
int top2=MaxSize-1;
}ShareStack;
3.2 基本操作
这里只拿进栈操作来实现,其余的可以自行动手练习。
3.2.1 栈1进栈:
bool Pop(ShareStack &S,ElemType e){
if((S.top1+1)==S.top2) return false; #栈满?
S.data[S.top1++]=e;
return true;
}
3.2.2 栈2进栈:
bool Pop(ShareStack &S,ElemType e){
if((S.top1+1)==S.top2) return false; #栈满?
S.data[S.top2--]=e;
return true;
}
4 栈的链式存储
4.1 链栈的定义
栈的链式存储称为链栈,采用单链表的头插法(不包含头结点),head指向栈顶结点。
typedef struct LNode{
ElemType *data;
struct LNode *next;
}LNode,*LStack;
4.2 链栈的基本操作
4.2.1 进栈
bool Pop(LStack &S,ElemType e){
LNode *p=(LNode*)malloc(sizeof(LNode));
if(S==NULL){
S=p;
p->next=NULL
}
else{
p->next=S->next;
S->next=p;
}
return true;
}
4.2.2 出栈
bool Push(LStack &S,ElemType &e){
if(S==NULL) return false;
if(S->next==NULL){
e=S->data;
S->next=NULL;
}
else{
e=S->data;
S->next=S->next->next;
}
return true;
}
4.3 链栈的优点
- 不链栈不存在满栈上溢的情况;
- 链栈便于结点的插入与删除;
- 入栈和出栈的操作都在表头。