其他分享
首页 > 其他分享> > 数据结构-栈

数据结构-栈

作者:互联网

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