定义
栈是一种只能在一端进行插入, 删除操作的线性表
就像糖葫芦, 只能在一端吃, 最先插进去的最后才能吃
相关概念
允许插入删除操作的一端称为栈顶, 另一端称为栈底
栈顶的当前位置是动态的, 该位置是由一个称为栈顶指针的指示器指示
栈的插入操作称为进栈或入栈, 删除操作称为退栈或出栈
不含元素的栈称为空栈
栈是一种"后进先出" 的结构, (LIFO), 操作不具有随机性
栈的基本操作
InitStack(&S)
: 初始化栈, 构造一个空栈, 分配内存空间
DestroyStack(&S)
: 销毁栈, 销毁并释放栈S所占用的内存空间
Push(&S, x)
: 进栈, 将x加入使之成为新的栈顶
Pop(&S, &x)
: 出栈, 若S非空, 则弹出栈顶元素, 并用x返回
GetTop(S , &x)
: 读栈顶元素; 若栈S非空, 则用x返回栈顶元素
StackEmpty(S)
: 判断一个栈是否为空, 则返回true, 否则返回false
公式
n个不同元素进栈, 出栈元素不同排列的个数为
顺序栈
利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素, 并指示栈顶的位置
定义栈
#define MaxSize 10//定义栈中元素的最大个数
typedef struct{
ElemType data{MaxSize}; //静态数组存放栈中元素
int top;//栈顶指针
}SqStack;
初始化一个栈InitStack(&S)
void InitStack(SqStack &S){
S.top=-1; //初始化栈顶指针
}
判断栈空StackEmpty(S)
bool StackEmpty(SqStack S){
if(S.top==-1){
return true;//栈空
}else{
return false;//不空
}
}
进栈Push(&S, x)
新元素进栈
bool Push(SqStack &S, ElemType x){
if(S.top==MaxSize-1){//栈满,报错
return false;
}
S.top = S.top+1;
S.data[S.top] = x;
return true;
}
出栈Pop(&S, &x)
bool Pop(SqStack &S, ElemType &e){
if(S.top==-1){
return false;//栈空, 报错
}
x = S.data[S.top]; //栈顶元素先出栈
S.top = S.top-1; //指针减1
return true;
}
读栈顶元素GetTop(S , &x)
bool GetTop(SqStack &S, ElemType &e){
if(S.top==-1){
return false;//栈空, 报错
}
x = S.data[S.top];
return true;
}
共享栈
定义栈
#define MaxSize 10
typedef struct{
ElemType data[MaxSize];
int top0;//0号栈栈顶指针
int top1;//1号栈栈顶指针
}ShStack;
初始化栈
void InitStack(ShStack &S){
S.top=-1;
S.top1=MaxSize;
}
链式栈的存储结构
采用链式存储的栈成为链栈, 是运算受限的单链表, 只能在链表头部进行操作
typedef struct Stacknode{
SElemType data;//数据域
struct Stacknode *next;//指针域
}StackNode, *LinkStack;
链式栈的特点
- 不存在栈满的情况
- 栈顶指针就是链表头指针
- 头插法建立单链表相当于进栈
- 单链表的删除相当于出栈