栈
-
什么是栈?
栈在实际的例子中有点像手枪的弹夹。你每次添加子弹的时候都是会把你前面添加的子弹给压到最下面。而打出来的子弹都是你最新的。所以就有一个特点,先进去的子弹会先出来。后进去的子弹回后出来。栈结构在网页中是很常用的一个数据结构。我们很经常用的浏览器的前进后退功能就是这样的。
栈是限定了仅在表尾(栈顶)进行插入删除的操作的线性表 -
栈的例子
注意:栈一定是遵循先进先出的原则。所以想想312这种情况会发生吗?还有一点栈其实也是一个线性表 -
栈的结构定义
栈的几种常见情况(顺序结构)
- 进栈
2. 出栈
- 优点:不会有进行删除的操作时有大量移动
- 缺点:还是数组的缺点,要事先明确栈的大小
为了解决这个大小的问题现在可以用两个完全一样的栈完成
将两个确定好的栈,变成一个数组。怎么变呢?
这样把,数组是有两个端点。我们的栈也是。那么我们可以在把其中一个栈的栈底放在数组的开始,另一个栈的栈顶放在数组的末端。就像这样
这样就有top控制着各自的栈
栈的链式结构
栈的链式结构和单链表是差不多的。只不多是头指针存着top
递归
回到数学问题。一对新兔子要两个月才能进行繁殖,有繁殖能力之后是每月繁殖一对。那么由问题可得
我们发现一下规律。发现相邻的两项构成了下一项。这就是著名的斐波那契数列
栈的应用
四则运算符(暂定)
队列
- 队列是只允许在一段(队头)进行删除,另一端(队尾)进行插入的线性表。大白话就是先进先出,也就是我们的排队结账。既然是线性表,那么他就符合线性表的所有特性,只不过是删除和插入不一样
顺序队列
插入数据
删除数据(和顺序结构的删除是一样的逻辑,这样他的时间复杂度就是On)
为了可以提高性能。用空间去换取时间。所以此时需要两个指针去控制两个整个队列
例子:
这样就是一个顺序的队列。但是问题又来了,当我还需要插入的时候,你的rear已经在末尾了,从我们前面的学习可以知道。现在的队列已经满了,你插不进去了,实际的情况我们还有两个位置。这个情况就叫做假溢出。
循环队列
为了解决假溢出,现在引进一个循环队列。将上面的图再改进一遍。rear指到了最后的时候就指回去第一个
那么问题又来了,现在队空的时候是rear == front,队满呢?
方法一:借助一个变量flag,对空的时候是flag=0,队满的时候是flag=1
方法二:始终预留一个位置。预留了位置,我们也需要去一些表达式去判断
(rear + 1 ) % size ==front