队列(queue)简称对,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。
在队列中把插入元素的一端称为队尾(rear),删除元素的一端称为队首(front)。向队列中插入元素称为进队或入队,新元素入队后成为新的队尾元素。从队列中删除元素称为离队或出队,元素出对后,其后续元素成为新的队首元素。
由于队列的插入和删除操作分别在队尾和队首进行,每个元素必然按照入队次序离队,也就是说先进队的元素必然先离队,所以队列成为先进先出表(First In First Out 简称 FIFO)。
数组结构的队列:
链表结构的队列:
使用Java实现队列的功能
1.自定义异常类,方便提示信息
package com.exception;
public class NullQueueException extends RuntimeException {
public NullQueueException(){
super();
}
public NullQueueException(String message){
super(message);
}
}
2.新建一个Queue类,实现队列的功能
package com.util;
import com.exception.NullQueueException;
public class Queue<T> {
private class Node{//定义内部类,存储数据和结点关系
private T data;//要存储的数据
private Node next;//后继结点
private Node pre;//前驱结点
public Node(){}
public Node(T data){
this.data = data;
}
}
private Node head = new Node();//双向链表的第一个元素
private Node last = new Node();//双向链表的最后一个元素
private int size;//队列的大小
public Queue(){
//设置链表关系
this.head.next = this.last;
this.last.pre = this.head;
this.size = 0;//初始化队列长度为0
}
public int getSize(){//取得队列的大小
return this.size;
}
public boolean isEmpty(){//判断队列是否为空
return this.size==0;
}
public void push(T e){//数据元素e入队
Node newNode = new Node(e);//新建结点
Node beforeNode = this.last.pre;//取得链表最后一个结点作为要插入节点的前驱节点
newNode.next = this.last;//设置新加入结点的后继节点为最后一个节点
this.last.pre = newNode;//设置链表最后一个结点的前驱节点为新结点
newNode.pre = beforeNode;//设置新加入结点的前驱节点为上一个节点
beforeNode.next = newNode;//设置上一个节点的后继节点为新加入结点
this.size++;//队列长度+1
}
public T pop(){//队首元素离队
if(this.size>0){//队列内有元素,可以离队
Node frontNode = this.head.next;//找到队首元素
this.head.next = frontNode.next;//设置队首元素的前驱结点的后继节点为队首元素的后继节点
frontNode.next.pre = this.head;//设置队首元素的后继节点的前驱节点为链表的第一个元素
this.size--;//队列长度-1
return frontNode.data;
}else{
throw new NullQueueException("******队列中没有数据******");
}
}
public T peek(){//取得队首元素
if(this.size>0){//队列内有元素
Node frontNode = this.head.next;//找到队首元素
return frontNode.data;
}
return null;
}
}
3.编写测试程序,观察队列的功能是否实现完全。
package com.test;
import com.util.Queue;
public class TestQuery {
public static void main(String[] args) {
Queue<String> stack = new Queue<String>();
stack.push("A");//A入队
stack.push("B");//B入队
stack.push("C");//C入队
System.out.println("队列是否为空:"+stack.isEmpty());
System.out.println("队列大小:"+stack.getSize());
System.out.println("出队:"+stack.pop()+"\t\t队列大小:"+stack.getSize());
System.out.println("出队:"+stack.pop()+"\t\t队列大小:"+stack.getSize());
System.out.println("出队:"+stack.pop()+"\t\t队列大小:"+stack.getSize());
stack.push("F");
System.out.println("入队F"+"\t\t队首数据:"+stack.peek()+"\t\t队列大小:"+stack.getSize());
System.out.println("出队:"+stack.pop()+"\t\t队列大小:"+stack.getSize());
System.out.println("出队:"+stack.pop()+"\t\t队列大小:"+stack.getSize());
}
}