栈(stack)
核心思想:限定仅仅在表尾(栈顶)进行插入和删除操作的线性表。
定义:1.允许插入和删除的一端称为栈顶,另一端称为栈底。
2.后进先出(Last In First Out)
3.不含任何元素时称为空栈
4.栈不仅有顺序存储结构(简称顺序栈),还有链式存储结构(简称链栈)。
栈的插入:叫做进栈(也叫压栈、入栈),时间复杂度为O(1)
栈的删除:叫做出栈(也叫弹栈),时间复杂度为O(1) 注:顺序栈和链栈的出入栈时间复杂度都为O(1)
如何方便理解和记忆:
1.把顺序栈想象成一个弹夹
入栈就像把子弹装入弹夹,出栈就像射击打出子弹。先装入的子弹是在弹夹的底部(也就是栈底),而先射出的子弹是后放入的子弹(也就是栈顶)。也可以看出入栈都是在栈顶进行的。
2.链栈
对于链栈来说是不需要头结点的,链栈基本不会出现栈满的情况,除非内存已经没有可以使用的空间。
链栈如果是空栈,即head=NULL。
入栈(push):在栈顶操作,把栈顶的指针移到上一位(要插入新元素)。
出栈(push):在栈顶操作,把栈顶的指针移到下一位,释放栈顶元素。
顺序栈和链栈的区别
相同:
(1) 时间复杂度均为O(1)
(2) 出入栈的思想,即都是在栈顶进行操作
不同:
(1) 从空间性来讲:顺序栈需要先确定一个固定的长度,也许会出现内存空间浪费的情况。
(2) 从存取定位来讲:顺序栈存取时定位很方便,而链栈要求每个元素都有指针域,增加了内存开销。
总结:
元素变化不确定,最好使用链栈。如果元素的变化都在可控范围则使用顺序栈。
举个例子:如果按1、2、3、4、5这个顺序入栈,出栈顺序是否只有5、4、3、2、1一种。答案是:当然不是。
虽然栈是先进后出,但是没有规定他需要全部进完才能出,这时候就会有很多种出栈顺序。
比如:
出栈顺序1、2、3、4、5 → 1进1出,2进2出,3进3出,4进4出,5进5出
出栈顺序5、4、3、2、1 → 1、2、3、4、5进,5、4、3、2、1出
出栈顺序3、2、1、5、4 → 1、2、3进,3、2、1出, 4、5进,5、4出
还有很多种排序,就不一一列举了,懂这个思路就可以。