栈和队列
栈(stack)是一个先进后出的(LIFO)的线性表,只能在表尾进行插入和删除工作。
栈的插入push和删除pop
栈的顺序存储和链式存储结构
顺序存储的栈包含了三个元素:base, top, stacksize。即栈底指针,栈顶指针和当前最大容量。
出栈是在栈顶取出数据,top-1,弹出一个数据,栈长也-1.
入栈是在栈顶加数据,top+1,栈长+1
注意:栈底的第一位为0,如果是空栈,top=-1,因为top是指向栈顶最后一位的上一位。
销毁栈和清空栈不同:销毁是要释放这个栈占据的物理内存空间
中缀表达式转后缀表达式规律:从左到右遍历中缀表达式的每一个数字和符号,数字直接输出,若是符号要判断它与栈顶符号的优先级,是右括号或者优先级低于栈顶符号,则栈顶符号依次出栈并输出。直到遇到左括号或者优先级更高的符号才入栈。
队列
queue 只允许在一段进行删除操作,在另一端进行插入操作的线性表,先进先出FIFO。有两个指针,一个指向队头一个指向队尾。头结点不是必要的,但是有的话更方便。
队列的链式存储结构
栈一般用顺序表来实现,但是队列一般用链表来实现,简称链队列。
空表
入队列操作过程,插入e2
出队列操作,移出e1
将队列的第一个元素移出,对头指针不发生变化,改变头结点的next指针即可。
栈:插进去抽出来
队列:插进去吐出来
特殊情况:原队列只有一个元素,就要处理队尾指针。
销毁队列
链队列建立在内存的动态区,因此,队列不再有用的时候要及时释放掉。
队列的顺序存储结构
假设有n个元素,则要建立一个大于n的存储单元,把队列的所有结构储存到前n个单元,数组下标为0的是队头
入队容易,出队难,因为所有元素都要向前移动,复杂度O(n)
如果对头指针可以灵活运用,不限制指向下标0,就解决了复杂度问题了
但是会出现假溢出的情况
可以用循环队列来解决这个问题,后面满了就从头填充,形成首位相接的环。
队列的循环链表演示 rear和front都会改变。他们的指针不断加一,即使超过也可以重头开始。应用取模算法解决假溢出,就是取余数,余数永远不会大于除数。
(rear+1)/栈长
(front+1)/栈长
结合动画考虑,rear和front重合就说明栈满了