数据结构基础讲解(四)——栈专项练习

本文数据结构讲解参考书目:

通过网盘分享的文件:数据结构  C语言版.pdf
链接: https://pan.baidu.com/s/159y_QTbXqpMhNCNP_Fls9g?pwd=ze8e 提取码: ze8e

数据结构基础讲解(三)——线性表之循环链表专项练习-CSDN博客

个人主页:樱娆π-CSDN博客

 

目录

 

栈的定义和特点

栈的类型定义

栈的基本操作

顺序栈的表示和实现

1.顺序栈的初始化

【算法步骤】

【算法实现】

2.顺序栈的入栈

【算法步骤】

【算法实现】

3.顺序栈的出栈

【算法步骤】

【算法实现】

4.取栈顶元素

【算法实现】

链栈的表示和实现

1.链栈的初始化

【算法实现】

2.链栈的入栈

【算法步骤】

【算法实现】

3.链栈的出栈

【算法步骤】

【算法实现】

4.取栈顶元素

【算法实现】

栈与递归


 


栈的定义和特点

栈 (stack) 是限定仅在表尾进行插入或删除操作的线性表。 因此, 对栈来说, 表尾端有其 特殊含义, 称为栈顶 (top), 相应地, 表头端称为栈底 (bottom)。 不含元素的空表称为空栈

栈又称为后进先出 (Last In First Out, LIFO) 的线性表。

由图可知,出栈和入栈都是在栈顶进行的!!

栈的类型定义

栈的基本操作除了入栈和出栈外, 还有栈的初始化、 栈空的判定,以及取栈顶元素。

ADT Stack {

 数据对象: D={ai I ai含于EElemSet, i=1, 2, …, n,n>=0}

数据关系: R= { < ai-1, ai > I ai-1,ai含于D, i=2, …, n}

约定 an 端为栈顶, a1端为栈底

基本操作:

}

栈的基本操作

基本操作初始条件操作结果
InitStack(&S)/构造一个空栈s
DestroyStack(&S)栈S已存在栈S被销毁
ClearStack(&S)栈S已存在将S清为空栈
StackEmpty(S)栈S已存在若栈 s 为空栈, 则返回 true, 否则返回 false
StackLength (S)栈S已存在返回s的元素个数, 即栈的长度。
GetTop(S)栈S已存在且非空返回s的栈顶元素, 不修改栈顶指针
Push(&S,e)栈S已存在插入元素e为新的栈顶元素
Pop(&S,&e)栈S已存在且非空删除S的栈顶元素,并用e返回其值
StackTraverse(S)栈S已存在且非空从栈底到栈顶依次对S的每个数据元素进行访问

顺序栈的表示和实现

顺序栈是指利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到 栈顶的数据元素,同时附设指针 top指示栈顶元素在顺序栈中的位置。通常习惯的做法是:以top=0表示空栈。

//----- 顺序栈的存储结构- ----
#define MAXSIZE 100          //顺序栈存储空间的初始分配址
typedef struct
{
SElernType *base;       //栈底指针
SElernType *top;        //栈顶指针
int stacksize;          //栈可用的最大容量

}SqStack; 

https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=%C2%A0%E9%A1%BA%E5%BA%8F%E6%A0%88%E4%B8%AD%E6%95%B0%E6%8D%AE%E5%85%83%E7%B4%A0%E5%92%8C%E6%A0%88%E6%8C%87%E9%92%88%E4%B9%8B%E9%97%B4%E7%9A%84%E5%AF%B9%E5%BA%94%E5%85%B3%E7%B3%BB&pos_id=9budAonz
标顺序栈中数据元素和栈指针之间的对应关系题

注:base 为栈底指针, 初始化完成后, 栈底指针 base 始终指向栈底的位置, 若 base 的值为NULL, 则表明栈结构不存在。 top 为栈顶指针, 其初值指向栈底。 每当 插入新的栈顶元素时, 指针 top 增1; 删除栈顶元素时, 指针 top 减l。 因此, 栈空 时, top 和 base 的值相等, 都指向栈底;栈非空时, top 始终指向栈顶元素的上一个 位置。

1.顺序栈的初始化

【算法步骤】
  1. 为顺序栈动态分配一个最大容最为MAXSIZE 的数组空间, 使 base 指向这段空间的基地 址, 即栈底。
  2. 栈顶指针 top 初始为 base, 表示栈为空。
  3. stacksize 置为栈的最大容鼠MAXSIZE
【算法实现】
Status InitStack(SqStack &S) 
{//构造一个空栈s
S.base=new SElemType[MAXSIZE];     //为顺序栈动态分配一个最大容扯为 MAXSIZE 的数组空间
if (! S. base) exit (OVERFLOW) ;     //存储分配失败
S.top=S.base;                //top 初始为 base, 空栈
S.stacksize=MAXSIZE;          //stacksize 置为栈的最大容量 MAXSIZE
return OK;
}

2.顺序栈的入栈

【算法步骤】
  1. 判断栈是否满, 若满则返回ERROR
  2. 将新元素压入栈顶, 栈顶指针加1
【算法实现】
Status Push (SqStack &S, SElemType e) 
{//插入元素e为新的栈顶元素
if(S.top-S.base==S.stacksize) return ERROR; //栈满
*S.top++=e; //元素 e 压入栈顶, 栈顶指针加 1
return OK;
}

3.顺序栈的出栈

【算法步骤】
  1. 判断栈是否空, 若空则返回ERROR
  2. 栈顶指针减1, 栈顶元素出栈
【算法实现】
Status Pop(SqStack &S,SElemType &e) 
(//删除s 的栈顶元素, 用 e 返回其值
if(S.top==S.base) return ERROR;       //栈空
e=*--S.top;              //栈顶指针减 1, 将栈顶元素赋给e
return OK;  
}

4.取栈顶元素

当栈非空时, 此操作返回当前栈顶元素的值, 栈顶指针保待不变

【算法实现】
SElemType GetTop{SqStack S) 
{//返回 s 的栈顶元素, 不修改栈顶指针
if{S.top! =S.base)      //栈非空
return *{S.top-1);       //返回栈顶元素的值,栈顶指针不变
}

链栈的表示和实现

链栈示意图

 由于栈的主要操作是在栈顶插入和删除, 显然以链表的头部作 为栈顶是最方便的, 而且没必要像单链表那样为了操作方便附加一 个头结点。

1.链栈的初始化

链栈的初始化操作就是构造一个空栈, 因为没必要设头结点, 所以直接将栈顶指针置空即可

【算法实现】
Status InitStack(LinkStack &S) 
{//构造一个空栈 s, 栈顶指针置空
S=NULL; 
return OK; 
}

2.链栈的入栈

【算法步骤】
  1. 为入栈元素 e 分配空间, 用指针 p 指向
  2. 将新结点数据域置为e
  3. 将新结点插入栈顶
  4. 修改栈顶指针为 p

【算法实现】
Status Push(LinkStack &S, SElemType e) 
{//在栈顶插入元素e
p=new StackNode; 
p->data=e; 
p->next=S; 
S=p; 
return OK;
}

3.链栈的出栈

【算法步骤】
  1. 判断栈是否为空 , 若空则返回ERROR
  2. 将栈顶元素赋给e
  3. 临时保存栈顶元素的空间, 以备释放
  4. 修改栈顶指针, 指向新的栈顶元素
  5. 释放原栈顶元素的空间

【算法实现】
Status Pop(LinkStack &S,SElemType &e) 
{//删除 s 的栈顶元素,用 e 返回其值
if(S==NULL) return ERROR; 
e=S->data;
p=S; 
S=S->next; 
delete p; 
return OK; 
}

4.取栈顶元素

与顺序栈一样, 当栈非空时, 此操作返回当前栈顶元素的值, 栈顶指针S保持不变

【算法实现】
SElemType GetTop(LinkStack S) 
{//返回 s 的栈顶元素, 不修改栈顶指针
if(S! =NULL) 
return S->data;
}

栈与递归

所谓递归是指,若在一个函数、 过程或者数据结构定义的内部又直接(或间接)出现定义本身 的应用,则称它们是递归的, 或者是递归定义的。在以下三种情况下, 常常使用递归的方法:

  1. 定义是递归的
  2. 数据结构是递归的
  3. 问题的解法是递归的

————由于博主还是大三的在读生,时间有限,每天会不定时更新一些学习经验和一些32的项目,如果喜欢就点点关注吧,大佬们!!!!———— 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

樱娆π(准备保研版)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值