带尾节点的链表
我们之前实现的链表,只有链表头节点head。链表对中间元素的操作时间复杂度为O(n),因此要对链表的结构进行优化。需要多维护一个尾节点的变量(tail),对链表头元素的add 和remove操作都是O(1),链表尾元素add操作为O(1),而对链表尾元素remove操作时间复杂度为O(n)。结合队列FIFO的特点,决定在尾节点tail处添加元素,而在链表头head处删除元素,这样实现的队列添加删除操作的时间复杂度都为O(1)。
话不多说,上代码
/*
* 基于优化的链表(带tail尾结点)实现队列
* */
public class LinkedListQueue<E> implements Queue<E> {
/*
*定义一个内部类Node
* */
private class Node<E>{
private E e;
private 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;
private Node tail;
private int size;
public LinkedListQueue(){
tail=null;
head=null;
size=0;
}
@Override
public void enqueue(E element) {
if(tail==null){
tail=new Node(element,null);
head=tail;
}else{
tail.next=new Node(element,null);
tail=tail.next;
}
size++;
}
@Override
public E dequeue() {
if(isEmpty()){
throw new IllegalArgumentException("队列为空,删除失败");
}
Node retNode=head;
head=head.next;
// 将删除的节点从链表中删除
retNode.next=null;
if(head==null){
tail=null;
}
size--;
return (E) retNode.e;
}
@Override
public E getFront() {
if(isEmpty()){
throw new IllegalArgumentException("队列为空");
}
return (E)tail.e;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return size==0;
}
@Override
public String toString(){
StringBuilder buffer=new StringBuilder();
buffer.append("Queue: front ");
Node cur=head;
while(cur!=null){
buffer.append(cur.e+"->");
cur=cur.next;
}
buffer.append("Null tail");
return buffer.toString();
}
public static void main(String[] args) {
LinkedListQueue<Integer> linkedListQueue=new LinkedListQueue<>();
for (int i = 0; i < 5; i++) {
linkedListQueue.enqueue(i);
System.out.println(linkedListQueue);
}
linkedListQueue.dequeue();
System.out.println(linkedListQueue);
}
}