队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列可以使用数组和链表这两种方式来实现,源码如下
定义队列行为接口InterfaceQueue.java
队列的几种行为都是确定的,不同的是底层如何实现,所以首先定义队列行为接口。声明最大队列长度为10,如果队列中元素超过了10则拒绝入队。
package queue;
import java.util.NoSuchElementException;
public interface InterfaceQueue<E> {
int MAX_SIZE = 10;
//入队(若失败则抛出IllegalStateException异常)
E add(E element) throws IllegalStateException;
//将指定元素插入队列,成功返回true,否则返回false
boolean offer(E element);
//获取队头的值,但不出队(若队列为空则抛出异常NoSuchElementException)
E element() throws NoSuchElementException;
//获取队头的值,但不出队(若队列为空则返回null
E peek();
//获取并移除队头(若队列空则返回null)
E poll();
//获取并移除队头(若队列空则抛出NoSuchElementException异常)
E remove() throws NoSuchElementException;
//获取当前队列中元素个数
int size();
//是否为空
boolean isEmpty();
//检查当前队列大小是否符合要求
boolean checkSize();
}
数组实现队列ArrayQueue.java
底层以Object数组来存储队列中的元素,声明cursor作为游标,cursor总是指向数组中的下一个空位置下标,操作数组队列时总是删除数组第一个元素,在数组尾部新增元素,同时cursor也可以表示为当前队列中元素的个数。
package queue;
import java.util.Arrays;
import java.util.NoSuchElementException;
/**
* @Author cuizx
* @Description 基于数组实现队列,该数组队列是固定长度的,如果超过了最大值则拒绝进入队列
* @Date 2019/10/2 11:15
* @Param
* @return
**/
public class ArrayQueue<E> implements InterfaceQueue<E>{
//记录数组队列中可以插入元素的位置
private int cursor;
private Object[] elementData;
public ArrayQueue(){
elementData = new Object[MAX_SIZE];
cursor = 0;
}
public E add(E element) throws IllegalStateException{
if(checkSize()){
elementData[cursor] = element;
cursor++;
return element;
}
throw new IllegalArgumentException();
}
public boolean offer(E element){
if(checkSize()){
elementData[cursor] = element;
cursor++;
return true;
}
return false;
}
public E element() throws NoSuchElementException{
if(isEmpty()){
throw new NoSuchElementException();
}
return (E)this.elementData[0];
}
public E peek(){
if(isEmpty()){
return null;
}
return (E)elementData[0];
}
public E poll(){
if(isEmpty()){
return null;
}
quickRemove();
return (E)elementData[0];
}
public E remove() throws NoSuchElementException{
if(isEmpty()){
throw new NoSuchElementException();
}
quickRemove();
return (E)elementData[0];
}
public int size(){
return cursor;
}
//检查是否当前队列已满
public boolean checkSize(){
if(size() >= MAX_SIZE){
return false;
}
return true;
}
public boolean isEmpty(){
return size() == 0;
}
private void quickRemove(){
E tempElement = (E)elementData[0];
Object[] targetElementData = new Object[MAX_SIZE];
System.arraycopy(elementData,1,targetElementData,0,MAX_SIZE-1);
elementData = targetElementData;
cursor--;
}
@Override
public String toString() {
return "ArrayQueue{" +
"cursor=" + cursor +
", elementData=" + Arrays.toString(elementData) +
", MAX_SIZE=" + MAX_SIZE +
'}';
}
}
链表实现队列
声明头部节点和游标节点,头部节点总是最先入队的节点,游标节点总是指向队尾的节点,在操作时总是删除队头的节点,在队尾新增节点。声明私有静态类Node,Node中item存储元素,next存储下一个Node的内存地址。
package queue;
import java.util.NoSuchElementException;
public class LinkedQueue<E> implements InterfaceQueue<E>{
//头部节点
private LinkedQueue.Node headNode;
//游标节点
private LinkedQueue.Node cursorNode;
//当前队列大小
private int size;
public LinkedQueue(){
size = 0;
}
public E add(E element) throws IllegalStateException {
if(checkSize()){
if(isEmpty()){
headNode = new LinkedQueue.Node<E>(element,null);
cursorNode = headNode;
}else{
LinkedQueue.Node<E> tempNode = new LinkedQueue.Node<E>(element,null);
cursorNode.next = tempNode;
cursorNode = cursorNode.next;
}
size++;
return element;
}
throw new IllegalStateException();
}
public boolean offer(E element) {
if(checkSize()){
if(isEmpty()){
headNode = new LinkedQueue.Node<E>(element,null);
cursorNode = headNode;
}else{
LinkedQueue.Node<E> tempNode = new LinkedQueue.Node<E>(element,null);
cursorNode.next = tempNode;
cursorNode = cursorNode.next;
}
size++;
return true;
}
return false;
}
public E element() throws NoSuchElementException {
if(isEmpty()){
throw new NoSuchElementException();
}
return (E)headNode.item;
}
public E peek() {
if(isEmpty()){
return null;
}
return (E)headNode.item;
}
public E poll() {
if(isEmpty()){
return null;
}
LinkedQueue.Node<E> tempNode = headNode;
headNode = tempNode.next;
size--;
return (E)tempNode.item;
}
public E remove() throws NoSuchElementException {
if(isEmpty()){
throw new NoSuchElementException();
}
LinkedQueue.Node<E> tempNode = headNode;
headNode = tempNode.next;
size--;
return (E)tempNode.item;
}
public int size() {
return size;
}
public boolean isEmpty() {
if(null == headNode){
return true;
}
return false;
}
//检查是否当前队列已满
public boolean checkSize(){
if(size() >= MAX_SIZE){
return false;
}
return true;
}
private static class Node<E> {
E item;
LinkedQueue.Node<E> next;
Node(E item, LinkedQueue.Node<E> nextNode) {
this.item = item;
this.next = nextNode;
}
}
@Override
public String toString() {
String headNodeStr = headNode ==null?"":headNode.item.toString();
String cursorNodeStr = cursorNode ==null?"":cursorNode.item.toString();
return "LinkedQueue{" +
"headNode=" + headNodeStr +
", cursorNode=" + cursorNodeStr +
", size=" + size +
'}';
}
}
测试代码QueueTest.java
package queue;
import java.util.Queue;
public class QueueTest {
public static void main(String[] args) {
testArrayQueue();
System.out.println();
testLinkedQueue();
}
private static void testArrayQueue(){
System.out.println("数组实现的队列测试开始--------------------");
InterfaceQueue<String> arrayQueue = new ArrayQueue();
arrayQueue.add("1");
arrayQueue.add("2");
arrayQueue.add("3");
System.out.println("插入元素123");
System.out.println(arrayQueue.toString());
System.out.println("插入元素4:"+arrayQueue.offer("4"));
System.out.println(arrayQueue.toString());
System.out.println("获取队列头的值:"+arrayQueue.element());
System.out.println(arrayQueue.toString());
System.out.println("获取队列头的值:"+arrayQueue.peek());
System.out.println(arrayQueue.toString());
System.out.println("获取并移除队头:"+arrayQueue.poll());
System.out.println(arrayQueue.toString());
System.out.println("移除队头:" + arrayQueue.remove());
System.out.println(arrayQueue.toString());
System.out.println("数组实现的列表测试结束--------------------");
}
private static void testLinkedQueue(){
System.out.println("链表实现的队列测试开始--------------------");
InterfaceQueue<String> linkedQueue = new LinkedQueue();
linkedQueue.add("1");
linkedQueue.add("2");
linkedQueue.add("3");
System.out.println("插入元素123");
System.out.println(linkedQueue.toString());
System.out.println("插入元素4:"+linkedQueue.offer("4"));
System.out.println(linkedQueue.toString());
System.out.println("获取队列头的值:"+linkedQueue.element());
System.out.println(linkedQueue.toString());
System.out.println("获取队列头的值:"+linkedQueue.peek());
System.out.println(linkedQueue.toString());
System.out.println("获取并移除队头:"+linkedQueue.poll());
System.out.println(linkedQueue.toString());
System.out.println("移除队头:" + linkedQueue.remove());
System.out.println(linkedQueue.toString());
System.out.println("链表实现的队列测试结束--------------------");
}
}