数据结构之美-03-栈

222 阅读2分钟

以下内容均来自极客时间专栏《数据结构与算法之美》

如何理解“栈”,后进者先出,先进者后厨,这就是栈的结构。从操作特性上来看,栈是一种“操作受限”的线性表,只允许在一端插入和删除数据。

什么情况下该使用栈?当某个数据集合只涉及在一端插入和删除数据,并且满足后进先出、先进后厨的特性,我们就可以使用栈结构。

栈可以用数组来实现,也可以用链表来实现。用数组实现的叫顺序栈,用链表实现的交链式栈。

不管是顺序栈还是链式栈,存储数据只需要一个大小为n的数组就够了,在入栈和出栈的过程,空间复杂度都是O(1)。出栈入栈只涉及个别数据的操作,所以时间复杂度都是O(1)。

在实现数组的动态扩容中,当数组空间不足的时候,就会先开辟一块更大的内存空间,然后把数据复制过去。 动态扩容的数组,出栈的时间复杂度是O(1),那入栈的复杂度是多少,最坏的情况复杂度是O(n),最好的情况是O(1),均摊时间复杂度的话,因为考虑到数据要做迁移,将n个数组均摊到n次入栈操作,每次入栈的时间复杂度是O(1),所以入栈的均摊时间复杂度是O(1)。

操作系统给每个线程分配一块独立的内存空间,这块内存是以栈结构来存储的。

在表达式中,栈是如何应用的?

从上图中可以看出,编译器通过两个栈来实现,一个保存操作数的占,一个保存运算符的栈,从左向右遍历,当遇到数组就入操作数栈,遇到运算符,就入运算符的栈。

思考题:

1、函数用栈来保存临时变量,为什么要用栈来保存临时变量。

答:这个其实跟函数的结构有关,函数符合先进先出的特性,所以用这种结构就比较适合。