什么是线性表?
线性表是 n 个数据元素的有限序列,最常用的是链式表达,通常也叫作线性链表或者链表。链表中存储的数据元素也叫作结点,一个结点存储的就是一条数据记录。每个结点的结构包括两个部分:
-
第一是具体的数据值;
-
第二是指向下一个结点的指针。
栈是什么?
栈是一种特殊的线性表。栈与线性表的不同,体现在增和删的操作。具体而言,栈的数据结点必须后进先出。
后进的意思是,栈的数据新增操作只能在末端进行,不允许在栈的中间某个结点后新增数据。
先出的意思是,栈的数据删除操作也只能在末端进行,不允许在栈的中间某个结点后删除数据。
也就是说,栈的数据新增删除操作只能在这个线性表尾进行,即在线性表的基础上加了限制。
栈既然是线性表,那么它也包含了表头和表尾。不过在栈结构中,由于其操作的特殊性,会对表头和表尾的名字进行改造。表尾用来输入数据,通常也叫作栈顶(top);相应地,表头就是栈底(bottom)。栈顶和栈底是用来表示这个栈的两个指针。跟线性表一样,栈也有顺序表示和链式表示,分别称作顺序栈和链栈。
顺序栈
栈的顺序存储可以借助数组来实现。一般会把数组的首元素存在栈底,最后一个元素放在栈顶。当需要新增数据元素,即入栈操作时,就需要将新插入元素放在栈顶,并将栈顶指针增加 1
删除数据元素,即出栈操作,只需要 将栈顶指针减1 就可以了。
对于查找操作,栈没有额外的改变,跟线性表一样,它也需要遍历整个栈来完成基于某些条件的数值查找。
链栈
关于链式栈,就是用链表的方式对栈的表示。通常,可以把栈顶放在单链表的头部。
新增数据的压栈操作,与链表最后插入的新数据基本相同。需要额外处理的,就是栈的 指针。插入新的数据,则需要让新的结点指向原栈顶。
在链式栈中进行删除操作时,只能在栈顶进行操作。因此,将栈顶的指针指向栈顶元素的 next 指针即可完成删除。对于链式栈来说,新增删除数据元素没有任何循环操作,其时间复杂度均为 O(1)。
对于查找操作,相对链表而言,链栈没有额外的改变,它也需要遍历整个栈来完成基于某些条件的数值查找。
总结
不管是顺序栈还是链栈,数据的新增、删除、查找与线性表的操作原理极为相似,时间复杂度完全一样,都依赖当前位置的指针来进行数据对象的操作。区别仅仅在于新增和删除的对象,只能是栈顶的数据结点。
栈具有后进先出的特性,当你面对的问题需要高频使用新增删除操作,且新增和删除操作的数据执行顺序具备后来居上的相反关系时,栈就是个不错的选择。例如浏览器的前进和后退等功能