根据单链表的特点,选择链表的头部作为队首,链表的尾部作为队尾。除了链表头
结点需要通过一个引用来指向之外,还需要一个对链表尾结点的引用,以方便队列的入队操
作的实现。为此一共设置两个指针,一个队首指针和一个队尾指针
1.抽象接口(我用的单链表的接口,之前在单链表中的文章中写过)
/*
* 队列接口
*/
public interface Queue {
//返回队列的大小
public int getSize();
//判断队列是否为空
public boolean isEmpty();
//数据元素入队
public void enQueue(Object obj);
//队首元素出队
public Object deQueue() throws QueueEmptyException;
//展现队首元素
public Object peek() throws QueueEmptyException;
}
/*
* 链表接口
*/
public interface Node {
//获取节点数据域
public Object getData();
//设置节点数据域
public void setData(Object obj);
//删除节点起关键作用
public Node getNext();
}
2.定义异常
/*
* 队列为空抛出该异常
*/
public class QueueEmptyException extends RuntimeException {
public QueueEmptyException(String err) {
super(err);
}
}
3.实现接口
/*
* 单链表的定义
*/
public class SLNode implements Node{
private Object element;
private Node next;
public SLNode() {
this(null,null);
}
public SLNode(Object element, Node next) {
this.element = element;
this.next = next;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
@Override
public Object getData() {
return element;
}
@Override
public void setData(Object obj) {
element = obj;
}
}
/*
* 队列实现接口
*/
public class QueueSLinked implements Queue {
// 队首
private SLNode front;
// 队尾
private SLNode rear;
// 队列大小
private int size;
public QueueSLinked() {
front = new SLNode();
rear = front;
size = 0;
}
/*
* 返回队列大小
*/
public int getSize() {
return size;
}
/*
* 判断队列是否为空
*/
public boolean isEmpty() {
return size == 0;
}
/*
* 数据元素入队
*/
public void enQueue(Object obj) {
SLNode p = new SLNode(obj, null);
rear.setNext(p);
rear = p;
size++;
}
/*
队首元素离队
*/
public Object deQueue() throws QueueEmptyException {
if(size<1)
throw new QueueEmptyException("队列为空,GG");
SLNode p = (SLNode) front.getNext();
front.setNext(p.getNext());
size--;
//只有一个元素,取完了,队首和队尾指在一起
if(size<1)rear=front;
return p.getData();
}
/*
取队首元素
*/
public Object peek() throws QueueEmptyException {
if(size<1)
throw new QueueEmptyException("队列为空,GG");
return front.getNext().getData();
}
}