关于栈,可以理解成一个操作受限的线性表,只允许在一端插入和删除数据。
事实上,从功能上来说,数组或者链表确实可以替代栈,但是从某种情况下,数组和链表暴露了更多的操作接口,使用时更容易出错。所以,当某个数据集合只涉及在一端插入和删除数据,并且满足后进先出,先进后出的特性,就可以使用栈这种数据结构。
其中,用数组实现的栈叫做顺序栈,用链表实现的栈,叫做链式栈。不管是顺序栈和链式栈,入栈和出栈的空间复杂度均为o(1)。
栈在函数调用中的应用:
操作系统为每个线程分配了一块独立的内存空间,这块内存被组织成栈这种结构,用来存储函数调用的临时变量。每进入一个函数,就会将临时变量作为一个栈入帧,当被调用函数执行完成,返回以后,将这个函数对应的栈帧出栈。
栈在表达式求值中的应用:
如进行四则运算的时候,编译器时通过俩个栈来实现的。其中一个保持操作数的栈,另一个保存运算符的栈。我们从左向右遍历表达式,当遇上数字,我们就之家压入操作栈,如果遇上运算符,那就与运算符栈的栈顶元素进行比较。
如果比运算符栈顶的元素的优先级高,就将当前运算符压入栈,如果低或者相同,从运算符栈中取栈顶运算符,从操作数栈的栈顶取2个操作数,然后进行计算,再把计算完的结果压入操作数栈,继续比较。
同理,如果出现了括号,那就再加一括号栈,当扫描到左括号时,将其压入栈中,当扫描到右括号时,从栈顶取出一个左括号,按 (),[],{},方式匹配。
JVM内存管理中栈和堆的区别:
内存空间在逻辑上分为三部分:代码区、静态数据区和动态数据区,动态数据区又分为栈区和堆区。
静态数据区:存储全局变量、静态变量、常量,常量包括final修饰的常量和String常量。系统自动分配和回收。
栈区:存储运行方法的形参、局部变量、返回值。由系统自动分配和回收。
堆区:new一个对象的引用或者地址存储在栈区,指向该对象存储在堆区的真实数据。