[TOC]
# 分析
带有尾指针的链表
![](https://box.kancloud.cn/b5f9d5e48eb2f32b1d9d43dbb5789ab5_1216x372.png)
改进下
从head端删除元素,从tail端插入元素
这边不用虚拟头节点
由于没有dummyHead,要注意链表为空的情况
# 代码
## 接口
~~~
public interface Queue<E> {
int getSize();
boolean isEmpty();
void enqueue(E e);
E dequeue();
E getFront();
}
~~~
## 实现类
~~~
public class LinkedListQueue<E> implements Queue<E> {
private class Node {
public E e;
public Node next;
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return e.toString();
}
}
//头节点和尾节点
private Node head, tail;
private int size;
public LinkedListQueue() {
head = null;
tail = null;
size = 0;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
//入队
@Override
public void enqueue(E e) {
//是空,表示整个是空
if (tail == null) {
//直接插入
tail = new Node(e);
head = tail;
} else {
//从tail端插入元素
tail.next = new Node(e);
//插入后的元素就在tail的后面
tail = tail.next;
}
//维护下size
size++;
}
//出队操作
@Override
public E dequeue() {
if (isEmpty()) {
//如果是空的队列就不能出队
throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
}
//出队从头部出,这个元素就是出队的元素
Node retNode = head;
//把头指针指向出队元素的下一个,但是要注意指向null的情况
head = head.next;
retNode.next = null;
//当这个头指针指向null,表示队列是空
if (head == null) {
tail = null;
}
//维护下size
size--;
return retNode.e;
}
@Override
public E getFront() {
if (isEmpty()) {
//如果是空的队列就不能出队
throw new IllegalArgumentException("Queue is empty.");
}
return head.e;
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Queue: front ");
Node cur = head;
while (cur != null) {
res.append(cur + "->");
cur = cur.next;
}
res.append("NULL tail");
return res.toString();
}
public static void main(String[] args) {
LinkedListQueue<Integer> queue = new LinkedListQueue<Integer>();
for (int i=0; i<10; i++) {
queue.enqueue(i);
System.out.println(queue);
if (i%3 == 2) {
queue.dequeue();
System.out.println(queue);
}
}
}
}
~~~
## 测试
~~~
public static void main(String[] args) {
LinkedListQueue<Integer> queue = new LinkedListQueue<Integer>();
for (int i=0; i<10; i++) {
queue.enqueue(i);
System.out.println(queue);
if (i%3 == 2) {
queue.dequeue();
System.out.println(queue);
}
}
}
~~~