队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,
package com.hqw.queue;
/**
* @author hqw521@qq.com
* @date 2018/6/6 20:27
*/
public class LinkedListQueue<E> implements Queue<E>{
private class Node {
public E value;
public Node next;
public Node(E value, Node next) {
this.value = value;
this.next = next;
}
public Node(E value) {
this(value, null);
}
public Node() {
this(null, null);
}
@Override
public String toString() {
return value.toString();
}
}
private Node head;
private Node 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 value) {
if (tail == null) {
tail = new Node(value);
head = tail;
} else {
tail.next = new Node(value);
tail = tail.next;
}
size++;
}
@Override
public E dequeue() {
if (isEmpty()) {
throw new IllegalArgumentException("dequeue failed,queue is empty");
}
Node temp = head;
head = temp.next;
temp.next = null;
if (head == null) {
tail = null;
}
size --;
return temp.value;
}
@Override
public E getFront() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is empty");
}
return head.value;
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Queue: front");
Node current = head;
while (current != null) {
res.append(current.value + " -> ");
current = current.next;
}
res.append("Null tail");
return res.toString();
}
}
循环队列与链队列比较:
1、时间上,它们的基本操作都是常数时间,即都为O(1),不过循环队列是事先申请好空间,使用期间不释放,而对于链队列,每次申请和释放节点也会存在一些时间开销,如果入队出队频繁,则两者还是有细微差异。
2、空间上、循环队列必须有一个固定的长度,所以就有了存储元素个数和空间的浪费的问题。而链队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但也可以接受。