栈
顺序栈
- top=-1 or top=0 (All right,c++ stack<> use -1)
- top==-1时,栈空;
top == Maxsize -1时,栈满;
top+1 == 栈长 。 - top ==0时,栈空;
top == Maxsize +0时,栈满;
top == 栈长。 - 共享栈:
(1) top1=-1,top2=Maxsize时,栈空;
(2) top2-top1=1时栈满。
(1) top1=0,top2=Maxsize-1时,栈空;
(2) top2-top1=0时栈满。
链式栈
- 所有操作都在头结点(头指针)进行。
- 栈空与链表空一样,链式栈不会满。
栈的输出序列个数 == 卡特兰数
https://editor.csdn.net/md/?articleId=105181692
快速判断输出序列是否错误
出栈序列中每一个元素之后所有比他小的元素会组成一个递减的序列。
队列
顺序队列
- front == 队头指针 == 指向队头元素,rear == 队尾指针 == 指向队尾元素+1,都从0开始。
- 出队入队操作:出队front+1,入队rear+1。
- 队长:rear-front。
- front == rear,队空;rear-front==Maxsize,队满。
如果,此时队头开始出队,明知道队没有满,但是局限于单一的+1操作,没有办法再利用空余的空间了,这就是假溢出。这个时候衍生出循环队列,其实顺序队列和循环队列都是顺序存储,只是指针改动有了变化。
循环队列
- front == 队头指针 == 指向队头元素,rear == 队尾指针 == 指向队尾元素+1,都从0开始。
- 出队操作:front =(front+1)%Maxsize。
- 入队操作:rear=(rear+1)%Maxsize。
很好理解,%在此的作用就像一个if语句,如果rear+1还小于Maxsize的时候就相当于简单的+1,如果rear+1等于Maxsize就把rear打回原形。front同理。 - 队长:(rear-front+Maxsize)%Maxsize。
+Maxsize相当于矫正rear小front大的情况 。 - front == rear,队空。
但是又会出现新的疑问,循环队列头尾相连,队满和队空的判断如果还是简单看到表面会混淆,因为判断式是一样的!
为此人们提出了空一格 - (rear+1)%Maxsize == front,如果rear再加一就和front一样了,那队满了。
当然还有别的办法:
例如,增加一个变量来计数;
例如,出队操作标识tag == 0,此时引起的front == rear是队空;入队操作标识tag ==1,此时引起的front == rear时队满。
链式队列
- front指向头结点,rear指向最后一个结点
- 入队操作在rear,没啥好说的;出队操作在front,需要特别注意,当出队是最后一个元素的时候,front和rear都需要变动了
- 当front和rear都指向了头结点队空。
双端队列
正常的双端队列如下:
输出受限的双端队列和输入受限的双端队列如下,当我们屏蔽一端就发现是一个栈,所以栈中合法的输出序列在输出受限的双端队列中均合法。剩下n!-f(n)个在栈中非法的,看看开启另一端会不会使他们合法。
这个要检验,没有什么快速的方法。
队列与栈的应用
- 栈用于括号的匹配;
- 栈用于表达式求值:
运算符的优先级:
总结几点:
1.栈外的(最大,压在一切运算符头上,到了栈内就最小;
2.遇到)就弹出直到遇到(;
3.所有的要入栈的运算符都是当它比栈顶运算符优先级大的时候压在上面,小的话就会弹出栈顶直到它可以压住时再入栈;
4.±之间栈内大,*/ 之间栈外大,两者之间肯定时 */大于±呀! - 栈用于递归;
- 队列用于层次遍历。