队列
也是一个链表,分为队首和队尾
元素只能从队尾入队,从队首出队
-
在队列类中有内部类Node<E>,两个使用final修饰的Node<E>对象,分别表示队首和队尾,使用指针相连接
-
出队操作是在队首进行
-
入队操作是在队尾进行
这是我自己的实现思路,双指针,可以有效避免插入或者删除操作中遍历带来的资源消耗:
队列结构:
package com.test.DataStructure.collection;
public class LinkedQueue<E> {
//end指向start
private Node<E> tail = new Node<>(null);
private final Node<E> head = new Node<>(null, tail);
int size = 0;
public static class Node<E> {
E element;
Node<E> next;
public Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
public Node(E element) {
this.element = element;
}
}
}
插入和删除方法:
在这里我的思路是将tail.next的指向作为队尾来使用,这样不用考虑到其余结点的指向问题,操作也比较简便:
public void offer(E e) {
if(size == 0){
Node<E> node = new Node<>(e);
tail.next = node;
head.next =node;
}
else{
Node<E> node = new Node<>(e);
tail.next.next = node;
tail.next = tail.next.next;
}
size++;
}
public void remove() {
if (size == 0) {
throw new IndexOutOfBoundsException("队列已空,不能删除");
}
head.next = head.next.next;
size--;
}
toString和isEmpty方法:
@Override
public String toString() {
if(size == 0){
throw new IndexOutOfBoundsException("队列已空");
}
StringBuilder stringBuilder = new StringBuilder();
Node<E> node = head.next;
while (node != null) {
stringBuilder.append(node.element).append(" ");
node = node.next;
}
return stringBuilder.toString();
}
public boolean isEmpty() {
return head.next == tail;
}