1.思维导图
1.逻辑结构
- 逻辑结构与线性表一致:一前一后,一对一的关系
- 只允许在一端插入和删除的线性表
- 栈顶:可进行插入和删除
- 栈底:不可进行插入和删除
- 空栈:线性表的空表
- 特点:后进先出(LIFO)
2.基本运算
3.常考题型
一般都是选择题给你abcd几个选项,判断某种出栈的顺序是否合法
3.存储结构实现栈
3.1顺序存储
3.1.1思维导图
3.1.2 “创”
- 初始化栈时,栈中还没有元素,而top指向的是栈顶元素,故让top=-1,表示目前无栈顶元素(栈为空)
#include <stdio.h>
#define MaxSize 10;
typedef int ElemType;
typedef struct{
ElemType data [MaxSize];//栈中可存放的数据元素的最多个数
int top;//栈顶指针---栈顶元素的数组下标
}SqStack;
//初始化栈
void InitStack(SqStack &S){
S.top = -1; //初始化栈顶指针
}
3.1.3判空
//判断栈空
bool StackEmpty(SqStack S){
if(S.top == -1) //栈空
return true;
else
return false; //不空
}
3.1.4入栈:“增”
//新元素入栈
bool Push(SqStack &S,ElemType x){
if(S.top == MaxSize-1) //栈满,报错
return false;
/*S.data[++S.top] = x;与下面的写法等价*/
S.top = S.top+1; //指针先+1
S.data[S.top] = x; //新元素入栈
return true;
}
3.1.5出栈:“删”
//出栈操作
//删除栈顶元素,并用变量x返回
/*注意:这样操作,元素只是在逻辑上被删除了,物理上还存储在内存空间中*/
bool Pop(SqStack &S,ElemType &x){
if(S.top == -1) //栈空,报错
return false;
/*等价于:x = S.data[S.top--];*/
x = S.data[S.top]; //栈顶元素先出栈
S.top = S.top-1; //指针再-1
return true;
}
3.1.6“查”:读栈顶元素
- 与出栈操作唯一不同的是出栈操作会让top--,往下移一位
- 读栈顶元素只是把此时top指针指向的数据元素用x给返回,但并不会让top指针下移
//读栈顶元素操作
bool Pop(SqStack &S,ElemType &x){
if(S.top == -1) //栈空,报错
return false;
x = S.data[S.top]; //x记录栈顶元素
return true;
}
3.1.7共享栈
引入:
-
顺序栈的问题:由于顺序栈用静态数组来存放数据元素,因此当这个静态数组被存满时,它的容量不可改变。
-
解决顺序栈容量不可更改的问题:
-
方式一:用链式存储的方式来实现栈,
-
方式二:在刚开始的时候给这个栈分配一个比较大片的连续的存储空间。但是刚开始就分配大片的存储空间,这会导致内存资源的浪费,
-
方式三:使用共享栈的方式来提高这一整片内存空间的利用率。
-
3.1.71概念
还是顺序存储的方式!!!
- 刚开始分配一片比较大的空间
- 采用两个top指针,代表这一片空间逻辑上存在两个栈;物理上是共享一片内存空间
- 一个top不断上移(top0++),表示这个在这个栈中插入元素(入栈)
- 一个top不断下移(top1--),表示这个在这个栈中插入元素(入栈)
- 初始
- top0=-1;
- top1=maxsize
- 判满:top0+1=top1
- 作用:一定程度上解决顺序栈的问题(缺点),提高这一整片内存空间的利用率。
3.1.72代码
//共享栈
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //静态数组存放栈中元素
int top0; //0号栈栈顶指针
int top1; //1号栈栈顶指针
}ShStack;
//初始化栈
void InitStack(ShStack &S){
S.top0 = -1;
S.top1 = MaxSize;
}
3.1.8总结
- 上述代码中,使用了变量声明的这种方式来分配相应的内存空间,并没有使用malloc函数。所以给这个栈分配的内存空间也会在栈相关的函数执行结束之后,由系统自动的回收
- 初始化top值:
- top=-1;表示top上移一个才到当前可插入元素的位置(未来的新栈顶)
- top=0;表示top目前已经指向可插入元素的位置(未来的新栈顶)
3.2链式存储(记得代码补坑)
3.2.1思维导图
3.2.2“创”
- 数据结构与单链表完全一致,且分为两类
- 带头结点
- 不带头结点(课本推荐)
- 二者判空代码不同!!!
3.2.入栈
- 与单链表头插法一致
3.2.出栈
- 即对于带头结点的单链表,在头结点处不断删除元素