以下笔记来自于学习,极客时间王争的课。
依次访问一串页面a-b-c之后,点击浏览器的后退按钮,可以查看之前浏览过的b和a,当停留在页面a时,点击前进按钮,可以再次查看页面b和c。但如果是在页面b时,进入到页面d后,则无法再次通过前进和后退按钮查看页面c。
栈:后进者先出,先进者后出。
操作特性上来看,栈是一种“操作受限”的线性表,只允许在一端插入和删除数据。
当某个数据集合只涉及在一端插入和删除数据,并且满足后进先出,先进先出的特性,就应首选“栈”这种数据结构。
栈既可以用数组来实现,也可以用链表来实现。用数组实现的栈,我们叫做顺序栈,用链表实现的栈,叫做链式栈。
支持动态扩容的顺序栈,在底层以来一个支持动态扩容的数组。当栈满了之后,申请一个更大的数组,将原来的数据搬移到新租中。
时间复杂度:
出栈操作,不涉及内存的重新申请和数据的搬移,所以出栈时间复杂度O(1)。对入栈来说,当栈中有空闲空间时,入栈操作的时间复杂度为O(1),当空间不足时,需要重新申请内存和数据搬移,时间复杂度变成O(N)。
栈在函数调用中的应用: 经典场景有函数调用栈。
栈在表达式求值中的应用:编译器通过两个栈来实现,其中一个保存操作书的栈,另一个保存运算符的栈。从左向右遍历表达式,当遇到数字,直接压入操作数栈;遇到运算符,就与运算符栈的栈顶元素进行比较。
栈在括号匹配中的应用。