脚踏实地《数据结构第三章栈和队列》第一节:栈

本节常考题型

问题一:有那些合法的出栈顺序?总数

在这里插入图片描述
进栈和出栈交替进行的话,就有上图中这么多的出栈顺序

一:栈的基础概念

在这里插入图片描述

1.1 栈(Stack)的基本概念(定义)

栈( Stack):是只允许在一端进行插入或删除操作线性表

生活中:烤串、叠碗等

一些术语:如图所示

  1. 栈顶:允许插入和删除的一端
  2. 栈底:不允许插入和删除的一端
  3. 栈顶元素
  4. 栈底元素
  5. 空栈

特点:后进先出
在这里插入图片描述

1.2 栈的基本操作

InitStack(&S):初始化栈。构造一个空栈S,分配内存空间。

DestroyStack(&L):销毁栈。销毁并释放栈S所占用的内存空间。

Push(&S,x):进栈,若栈s未满,则将x加入使之成为新栈顶。

Pop(&S,&x):出栈,若栈s非空,则弹出栈顶元素,并用x返回。

删除栈顶元素

GetTop(S,&x):读栈顶元素。若栈s非空,则用x返回栈顶元素。

不删除栈顶元素
栈的使用场景中大多只访问栈顶元素
在这里插入图片描述

常用操作:
StackEmpty(S):判断一个栈S是否为空。若S为空,则返回true,否则返回false。

1.3 知识回顾与重要考点

二:顺序栈(栈的顺序存储结构实现)

在这里插入图片描述

2.1 顺序栈的定义

在这里插入图片描述

#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
	ElemType data[MaxSize];//静态数组放栈中元素
	int top;//栈顶指针
} SqStack;

top是指向栈顶的元素位置,如上图所示


void testStack(){
	SqStack S;//声明一个顺序栈(分配空间)
	//。。。 后续操作 。。。
}

2.2 初始化操作

#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
	ElemType data[MaxSize];//静态数组放栈中元素
	int top;//栈顶指针
} SqStack;

//初始化栈
void InitStack(SqlStack &S){
	S.top = -1; //初始化栈顶指针
}

void testStack(){
	SqStack S;//声明一个顺序栈(分配空间)
	InitStack(S);
	//。。。 后续操作 。。。
}

2.3 判断栈空

//判断栈空
bool StackEmpty(SqStack S){
	if(S.top == -1)//栈空
		return true;
	else			//不空
		return false;
}

2.4 进栈操作(增)

#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
	ElemType data[MaxSize];//静态数组放栈中元素
	int top;//栈顶指针
} SqStack;

//新元素进栈
bool Push(SqStack &S,ElemType x){
	if(S.top == MaxSize-1)//栈满,报错
		return false;
	S.top = S.top + 1;//指针先加1
	S.data[S.top] = x;//新元素入栈
	return true;
}

在这里插入图片描述

2.5 出栈操作(删)

#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
	ElemType data[MaxSize];//静态数组放栈中元素
	int top;//栈顶指针
} SqStack;

//出栈操作
bool Pop(SqStack &S,ElemType $x){
	if(S.top == -1)	//栈空,报错
		return false;
	x=S.data[S.top];//栈顶元素先出栈
	S.top = S.top - 1;//指针再减1
	return true;
}

在这里插入图片描述

2.6 读取栈顶元素操作(查)

#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
	ElemType data[MaxSize];//静态数组放栈中元素
	int top;//栈顶指针
} SqStack;

//读取栈顶操作
bool Pop(SqStack &S,ElemType &x){
	if(S.top == -1)//栈空,报错
		return false;
	x=S.data[S.top];//x记录栈顶元素
	return true;
}

2.7 上面操作另一种实现方式(注意

在这里插入图片描述
如果想要将一个新的元素入栈的话,与之前的方式刚好相反

在这里插入图片描述

2.8 共享栈

顺序栈是使用静态数组零存放数据元素,因此静态数组的数据存满之后,其容量是不可以改变的,

解决上面的问题方法:

  1. 链式存储方式实现栈
  2. 在刚开始的时候给这个栈分配一个比较大片的连续存储空间(导致内存空间的浪费)
  3. 使用共享栈的方式提高第二种方式的空间利用率

共享栈:两个栈共享一片空间

代码实现:

# define MaxSize 10//定义栈中元素的最大个数
typedrf struct{
	ElemType data[MaxSize];//静态数组存放栈中元素
	int top0;//0号栈栈顶指针
	int top1;//1号栈战顶指针
} ShStack;

//初始化栈
void InitStack(ShStack &S){
	S.top0 = -1;//初始化栈顶指针
	S.top1 = MaxSize;
}

以后如果从0号栈存放指针的话,就是从下往上依次递增的,
如果要往1号栈放入数据元素的话,这个栈的栈顶就是从上往下依次递增的
如此在逻辑上实现了两个栈,但是在无论上又是共享同一片的存储空间,提高了空间利用率

栈满的条件: top0+ 1 == top1
在这里插入图片描述

2.9 知识回顾与重要考点

在这里插入图片描述
在路逻辑上清空一个栈,其实只需要将top指针指向初始化的那个位置就可以了

在本节中,我们是通过变量声明的方式分配内存空间,并没有使用malloc函数,所以给栈分配的内存空间会在函数运行结束后系统自动回收内存

三:链栈(栈的链式存储方式实现)

在这里插入图片描述

3.1 用链式存储方式实现的栈

用链式存储方式实现的栈,其本质上也是一个单链表,只不过我们想要规定只能在单链表的链头一端进行插入和删除操作(链头=栈顶

3.1.1 链栈的定义

typedef struct Linknode{
	ElemType data;//数据域
	struct Linknode *next;//指针域
}*LiStack;//栈类型定义

3.2 其他

剩下的操作与之前链表的操作类似,我在这里也偷懒了,不说了
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值