栈和队列都是线性表的推广和应用,简单来说,栈就是后进先出的线性表,队列是先进先出的线性表。

栈在平常的生活中也有很多应用,比如我们用浏览器打开很多网站,点击后退键的时候,越晚打开的网站越早出来,这就是后进先出。递归操作也是要用到栈。

栈的结构是这样的,下边堵住了,只允许从栈顶进行入栈出栈操作,这也是为什么栈会后进先出的原因。

java用栈实现先进先出_队列

像这个栈有三个元素,a1,a2,a3,全部入栈的话,按照后进的原则,它的出栈顺序的话,应该就是a3,a2,a1。但是如果不是全部入栈的话,还有其他出栈顺序,比如说a1先入栈,接着出栈,然后a2,a3入栈,出栈,这样的出栈顺序就是a1,a3,a2。这里有一个公式,n个不同元素进栈,出栈元素不同排列的个数为(2n)!/[(n+1)!n!],对于3个元素来说,就是5种情况。
跟一般的线性表一样,栈也有顺序存储和链式存储两种形式,顺序栈是这样描述的:

#define MaxSize 50
Typedef struct{
Elemtype struct{
Elemtype data[MaxSize];
Int top;
}SqStack;

进栈的时候,先判断栈是不是不满,不满的话栈顶指针先加1,然后送值到栈顶元素。

出栈的时候,也是要看一下这个栈是不是空的,如果非空的话,先取栈顶元素,然后将栈顶指针减1。

为了更好的利用存储空间,有这么一种栈,叫共享栈。

栈底分别在存储空间的两端。

Top0=-1时,0号栈为空,top1=MaxSize时1号栈为空。当这两个栈顶指针相邻的时候,top1-top0=1时,这两个栈就都满了。

java用栈实现先进先出_数据结构_02

用链式结构存储栈的好处是不存在栈满上溢的情况。但是要注意所有的操作都是要在表头进行,才能满足栈后进先出的特点。

java用栈实现先进先出_栈_03

队列和栈一样,也是一种操作受限的线性表,就跟我们平常排队先到先得一样,队列也是先进先出。在栈中插入和删除元素叫进栈出栈,在队列中叫出队入队。

同样的,队列的物理实现也分为顺序存储和链式存储。

首先是顺序存储,首先还是要找一块大的存储空间,先占下地方来,队列里有两个指针,对头指针front指向队头的元素,队尾指针rear指向队尾元素的下一个位置,也有的书上定义的是rear指向队尾元素。初始的时候,队伍为空,此时满足Q.front=Q.rear == 0。

在队列不满的时候入队,首先将值添加到队尾,然后队尾指针加1,在队列不空的时候出队,先得到对头的元素,然后将对头指针加1。

java用栈实现先进先出_队列_04

前面说到队空的时候有Q.front=Q.rear==0,为什么要加 ==0呢?只满足Q.front=Q.rear不能判断这个队列是空的吗?

java用栈实现先进先出_出栈_05

是不可以的,像这个例子,先入队5个元素,再出队四次,就变成现在这个情况,现在Q.front和Q.rear相等,但是此时队列中还有元素,自然不可能是空队列。

怎么解决这个假溢出的问题呢,要是到顶上这里在能往前走就可以了,于是就有了这样一种环式的队列。

java用栈实现先进先出_java用栈实现先进先出_06

初始时还是一样的:Q.front=Q.rear=0,不过这里的队首指针和队尾指针加1就跟以前不一样了,因为它到达顶部之后,又回到远点了,所以要与队列长度有一个求余的操作。