定义:栈又称为堆栈,是一种运算受限的线性表,这是因为它仅允许在线性表的固定一端(表尾)进行插入、删除和读取元素等运算,不允许在其他任何位置进行运算

特点:后进先出

时间复杂度:O(1)

Java 栈实现队列 java的栈和队列_堆栈

一、栈的基本操作:

在Java程序里面用Stack来描述栈的操作,这个类定义如下:
public class Stack< E > extends Vector< E >
可以发现Stack是Vector的子类,所以他底层是数组实现的,且是线程安全的,但他使用的并不是Vector类之中所提供的方法,而是采用如下的几种方法

1.push(E item);

入栈,向栈顶插入一个元素

Java 栈实现队列 java的栈和队列_Java 栈实现队列_02


**将项目推到此堆栈的顶部。**这与addElement(item)效果完全相同

参数:item–要推送到该堆栈上的项。

返回:项参数。

另见:Vector.addElement

可以发现,其调用的是父类Vector的addElement()方法

2.pop();

出栈,删除栈顶元素并返回

Java 栈实现队列 java的栈和队列_队列_03


移除此堆栈顶部的对象,并将该对象作为此函数的值返回。

返回:此堆栈顶部的对象(向量对象的最后一项)。

抛出:EmptyStackException–如果此堆栈为空。3.empty();

判断栈是否为空

Java 栈实现队列 java的栈和队列_java_04

这个就很显而易见了,调用父类的size方法获取元素个数,如果为0,则为空4.peek();

获取栈顶元素

Java 栈实现队列 java的栈和队列_Java 栈实现队列_05


查看此堆栈顶部的对象,而不将其从堆栈中移除。

返回:此堆栈顶部的对象(向量对象的最后一项)。

抛出:EmptyStackException–如果此堆栈为空。

6.search(Object o)

Java 栈实现队列 java的栈和队列_队列_06


返回对象在此堆栈上的基于1的位置(即若有多个相同的元素,只取离栈顶最近的)。如果对象o作为该堆栈中的一个项出现,则此方法返回从最接近堆栈顶部的引用堆栈顶部的距离;堆栈上最顶端的项被认为位于距离1处。equals方法用于将o与此堆栈中的项进行比较。

返回:离堆栈顶部最近的相同元素的离栈顶的距离;返回值-1表示对象不在堆栈上。

Stack类也可以直接调用其父类的方法,还有很多,这里就不一一列举了

队列

定义:队列简称队,也是运算受限的线性表,仅允许在表的一段插入,另一端删除。允许插入的一端做队尾,进行删除的一端做队首。

特点:先进先出

时间复杂度:O(1)

Java 栈实现队列 java的栈和队列_java_07

一、队列的基本操作

在Java程序里面用Queue来描述队列的操作,这个类定义如下:

public interface Queue extends Collection< E >

Java 栈实现队列 java的栈和队列_堆栈_08

显而易见,Queue是一个接口,他并不是一个类,他并没有实现的方法体,所以他的方法取决于右侧的实现类。

Queue qu=new LinkedList<>();

Queue使用时要尽量避免使用Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。它们的优点是通过返回值可以判断成功与否,add()和remove()方法在失败的时候会抛出异常。 如果要使用前端而不移出该元素,使用element()或者peek()方法。

1.offer();

如果可以在不违反容量限制的情况下立即将指定元素插入此队列中。如果队列已满直接返回false,队列未满则直接插入并返回true;

Java 栈实现队列 java的栈和队列_数据结构_09


可以发现其调用了add方法,但其有一个boolean类型返回值

当使用容量受限队列时,此方法通常比add更可取,因为add只能通过抛出异常来插入元素。

抛出:
ClassCastException–如果指定元素的类阻止将其添加到此队列中
NullPointerException–如果指定的元素为null且此队列不允许null元素
IllegalArgumentException–如果此元素的某些属性阻止将其添加到此queu

2.add();

是对offer()方法的简单封装.

如果可以在不违反容量限制的情况下立即将指定元素插入此队列,则会在成功时返回true,如果当前没有可用空间,则会引发IllegalStateException。

Java 栈实现队列 java的栈和队列_队列_10


add方法又再次调用了linkLast方法,来进行尾插。

Java 栈实现队列 java的栈和队列_堆栈_11

抛出:

IllegalStateException–如果此时由于容量限制而无法添加元素

ClassCastException–如果指定元素的类阻止将其添加到此队列中

NullPointerException–如果指定的元素为null且此队列不允许null元素

IllegalArgumentException–如果此元素的某些属性阻止将其添加到此队列中

3.poll();

检索并删除此队列的头,如果此队列为空,则返回null。

Java 栈实现队列 java的栈和队列_Java 栈实现队列_12


4.remove();

检索并删除此队列的头。此方法与轮询的不同之处在于,如果此队列为空,它将引发异常。

Java 栈实现队列 java的栈和队列_java_13


调用了LinkedList的移除首元素的方法。抛出:

NoSuchElementException–如果此队列为空

5.peek();

直接取出队头的元素,并不删除.

Java 栈实现队列 java的栈和队列_java_14


6.element();

如果队头元素存在则取出并不删除,与poll()功能相同,但是如果头元素不存在,则会抛出异常

Java 栈实现队列 java的栈和队列_数据结构_15


抛出:

NoTouchElementException–如果此队列为空

栈与队列速度快慢

1.栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。
2.队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快。

栈与队列的应用

在算法中最常见的便是dfs(深度优先搜索)与bfs(广度优先搜索)

dfs便可以用栈实现
深度优先搜索(DFS)按符合的条件一直向前搜索,以达到目标。但当探索到某一步时,发现原先选择并未达到要求或者无法到达,就退回一步重新选择,这种走不通就退回再选择其他路径的思想成为回溯(注意,回溯是一种思想),而满足回溯条件的某个状态的点称为“回溯点”。 这种探索+回溯思想,称为回溯法。

如迷宫问题,dfs可以找到到达终点的路(注意:不一定是最短路径),同时也可以知道走过的路径。

而bfs,则可以用队列实现
广度优先搜索(也称宽度优先搜索,缩写BFS)是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名。

如迷宫问题,bfs可以找到到达终点的最短路路,同时也可以知道到达每个点的所走步数。