ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据结构-栈

2021-03-24 13:31:37  阅读:301  来源: 互联网

标签:进栈 出栈 top 元素 栈顶 数据结构 指针


part 5栈

1 概念

1.1 现象

弹夹式手枪、洗盘子摞盘子、浏览器回退功能、word、画图的撤销操作

image-20210317154011741

 

1.2 特点

原理:后进先出(LIFO结构)

1 .3 定义

栈:限定在表尾进行插入(尾插法)或删除操作的线性表

栈顶(表尾)允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)。

空栈不含任何数据元素的栈。

压栈(进栈):栈的插入

出栈:栈的删除

 

1.4 逻辑示意图

image-20210302115728671

 

1.5 进栈出栈变化形式

最先进栈的只能最后出栈?

解析:栈对线性表的插入和删除的位置进行了限制,但没有对元素进出栈的时间进行限制

例如有三个整型数字1、2、3依次进栈,会有哪些出栈次序呢?

第一种:1、2、3进,再3、2、1出。出栈次序321

第二种:1 进、1出、2进、2出、3进、3出。出栈次序123

第三种:1进、2进、2出、1出、3进、2 出。出栈次序213

第四种:1进、1出、2进、3进、3出、2出。出栈次序为132

第五种:1进、2进、2出、3进、3出、1出。出栈次序231.

1.6 有没有可能是312这样的次序出栈呢?

不会。3先出栈,意味着3曾经进栈。3进栈意味着1和2已经进栈。那么出栈只能是321.

 

2 栈的顺序存储结构

 

顺序线性表采用数组实现。

2.1 思考---栈顶位置

采用数组空间首地址充当栈顶(表尾)还是栈底(表 头)?

答案:栈底:数组首元素

解析:

 插入:尾插法
 下标为0充当栈顶(表尾),每次插入数据,都需要数组整体后移

栈顶:定义一个top变量来指示栈顶元素在数组中的位置(数组定长,top=实际元素个数-1)

 

2.2 数据元素和栈指针的对应关系

image-20210302135657732

 stack_size:存储栈的长度
 top:栈顶位置(top<stack_size)
 top=0:数组里面只有一个元素
 top=-1:空栈
 top=stack_size-1:满栈

示例:游标卡尺,游标不能超过尺的长度

2.3 类型定义

 typedef   int   s_elem_type;//s_elem_type 根据实际情况而定
 typedef  struct
 {
     s_elem_type   data[MAXSIZE];
     int top;//栈顶指针
 }sq_stack;//静态栈,顺序栈

image-20210302135359273

 

2.4 初始化

image-20210302142605677

 

2.5 入栈操作

2.5.1 逻辑示意图

image-20210302140000397

2.5.2 算法步骤

 (1)判断是否满栈,若满则返回ERROR
 (2)将新元素压入栈顶,栈顶指针+1

2.5.2 示例代码

image-20210302142724285

2.6 出栈

2.6.1 算法步骤:

 (1)判断栈是否为空
 (2)栈顶元素出栈,栈顶指针减一

2.6.2 参考代码

image-20210302144024249

 

2.7 取值(练习)

2.7.1 算法步骤

 (1)栈是否非空
 (2)取值

2.7.2 参考代码

image-20210302144311376

2.8 小结

时间复杂度

没有涉及循环,时间复杂度为o(1).

缺点:必须事先确定数组存储空间大小,不够用的情况下,需要采用编程手段来扩展数组的容量。

3 链栈

3.1 类型定义

3.1.1栈顶位置

概念:栈只允许在栈顶进行插入和删除操作

思考:栈顶放在链表的头部还是尾部呢?

单链表必须存在头指针,栈顶指针也是必须的。两者可以合二为一。所以较好的办法是把栈顶放在单链表的头部。

由此 :单链表的头结点便失去意义。通常对于链栈来说,是不需要头结点的

3.1.2 逻辑示意图

image-20210302144620589

3.1.3 数据元素与栈顶指针对应关系

 满栈:不存在
 空栈:top==NULL

3.1.4 结构定义

image-20210302145543264

 

3.2 入栈

3.2.1 算法步骤

 (1)为入栈元素e分配结点空间,用指针p指向
 (2)将新节点数据域置为e;
 (3)将新节点指向原头结点
 (4)修改栈顶指针s指向新结点

3.2.2 入栈示意图

image-20210302150330042

 

3.2.3 参考代码

注意:跨函数修改头指针的值,需要采用二级指针(无头结点)

image-20210303145145830

 

 

3.3 出栈

3.3.1 算法步骤

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

3.3.2 示意图

image-20210302151401705

3.3.3 示例代码

错误代码示范:

image-20210302151554327

解析:需要在pop()函数内修改头指针s 的值,跨函数修改一级指针,应采用二级指针

正确答案

image-20210303145234353

3.3.4 运行结果

后进先出

image-20210303145314620

 

3.4 完整代码

image-20210303145439570

4 应用---数制的转换

当将一个十进制整数N转换为八进制时,在计算过程中,将N与8求余得到的八进制数的各位依次进栈,输出结果就是得到的八进制数

4.1 运算过程

image-20210302171647717

 

4.2 算法步骤

 (1)初始化一个空栈s
 (2)当十进制数N非零时,循环执行下列操作
         ·把N与8求余得到的八进制数压入栈S
         ·n更新为N与8的商
 (3)当栈非空时,循环执行一下操作
             ·弹出栈顶元素e;
             ·输出e

4.3 参考代码

链栈实现

4.3.1 入栈

(无头结点,头插法)

image-20210303145640767

4.3.2 出栈

image-20210302181624314

4.4 完整代码

image-20210303145730169

4.5 运行结果

image-20210303145749916

 

 

标签:进栈,出栈,top,元素,栈顶,数据结构,指针
来源: https://blog.csdn.net/qq_40844674/article/details/115173488

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有