栈是限定仅在表尾进行插入和删除操作的线性表。
    队列是只允许在一端进行插入操作、而在另一端进行删除操作的线性表。
    先进后出 栈
    我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的
    栈称为空栈。
    栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。
    栈的插入:进栈,压栈
    栈的删除:弹栈
    对于顺序栈,栈底是表头,栈顶是表尾
    对于链栈, 栈底是表尾,栈顶是表头。没有头结点
    4.4栈的顺序存储结构
    一开始要定义好数组大小
    top=-1 空栈
    4.5两栈共享空间
    stackoverflow
    判断是否满栈:top1+1==top2
    4.6栈的链式存储结构 —链栈
    不需要提前定义大小,原则上栈可以一直增长
    不需要头结点
    顺序栈和链栈
    时间复杂度都是一样的,都是O(1)
    空间复杂度,O(1)
    顺序栈需要事先确定一个固定长度,可能会浪费空间;但是存取定位很方便
    链栈,栈的长度无限制
    栈的应用-递归
    斐波那契数列
    迭代和递归的区别是:迭代使用的是循环结构(while for),递归使用的是选择结构(if)。
    递归能使程序的结构更清晰、更简洁、更容易让人理解,从而减少读懂代码的时间。
    但是大量的递归调用会建立函数的副本,会耗费大量的时间和内存。
    迭代则不需要反复调用函数和占用额外的内存。
    因此我们应该视不同情况选择不同的代码实现方式。
    有时候使用递归虽然很简洁,但是时间效率有可能很差。
    对于这种题目,我们可以用递归来分析问题,
    但是写代码的时候,用数组来保存中间结果,基于循环实现。
    绝大部分动态规划题目,都是按照这两步做的
    编译器使用栈来实现递归
    栈的应用:四则运算求值
    四则运算表达式求值:后缀表示法(逆波兰表示法)。
    中缀表达式转为后缀表达式:
    要想让计算机具有处理我们通常的标准(中缀)表达式的能力,最重要的就是两步:
    1.将中缀表达式转化为后缀表达式(栈用来进出运算的符号)。
    2.将后缀表达式进行运算得出结果(栈用来进出运算的数字)。
    队列Queue
    只允许在一端进行插入操作,而在另一端进行删除操作的线性表
    FIFO 先进先出
    4.12队列的顺序存储结构
    队列顺序结构的不足:假溢出
    解决:循环队列
    front 指向队头元素
    rear 指向队尾元素的下一个位置
    循环队列满的条件是
    (rear+1)%QueueSize == front
    通用的计算循环队列长度公式为
    (rear-front+QueueSize)%QueueSize
    链队列一定有头结点
    空队列,front和rear都指向头结点
    总的来说,在可以确定队列长度最大值的情况下,建议用循环队列,如果你无法预估队列的长度时,则用链队列。
    栈和队列,都是特殊的线性表,只不过对插入和删除做了限制