概述
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。队列具有先进先出FIFO(FirstIn First Out)的特性。
队尾:进行插入操作的端称为队尾
队头:进行删除操作的端称为队头
Queue
从上面类的继承关系图可以看到Queue是一个接口,它的内部主要定义了以下几个方法:
方法名 | 返回值类型 | 说明 |
---|---|---|
offer(E e) | boolean | 将指定的元素插入到此队列中 |
add(E e) | boolean | 将指定的元素插入到此队列中 |
poll( ) | E | 检索并删除此队列的头 |
remove( ) | E | 检索并删除此队列的头 |
peek( ) | E | 取出队头的元素,但不删除 |
element() | E | 取出队头的元素,但不删除 |
1.offer( )和add( )方法的区别
- 对于offer():往队列添加元素。在不违反容量限制的情况下立即执行,将指定的元素插入到队列中。如果队列已满直接返回false,队列未满则直接插入并返回true;
- 对于add():如果队列已满,抛出异常IllegalStateException。
2.poll( )和remove( )方法的区别
- 对于poll():检索并删除此队列的头,如果此队列为空,则返回 null ;
- 对于remove():检索并删除此队列的头。 此方法与poll不同之处在于,如果此队列为空,它将抛出异常。
3.peek()和element( )方法的区别
- 对于peek():检索但不删除此队列的头部,如果此队列为空,则返回 null ;
- 对于element():检索但不删除这个队列的头。 此方法与peek的不同之处在于,如果此队列为空,它将抛出异常。
队列的模拟实现
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。
class Node {
int val;
Node next;
Node(int val, Node next) {
this.val = val;
this.next = next;
}
Node(int val) {
this(val, null);
}
}
public class MyQueue {
private Node head = null;
private Node tail = null;
private int size = 0;
public void offer(int v) {
Node node = new Node(v);
if (tail == null) {
head = node;
} else {
tail.next = node;
}
tail = node;
size++;
}
public int poll() {
if (size == 0) {
throw new RuntimeException("队列为空");
}
Node oldHead = head;
head = head.next;
if (head == null) {
tail = null;
}
size--;
return oldHead.val;
}
public int peek() {
if (size == 0) {
throw new RuntimeException("队列为空");
}
return head.val;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
}