像栈一样,队列(queue)也是表,然而,使用队列时插入在一端进行而删除在另一端进行。
队列的基本操作时enqueue入队,它是在表的末端(队尾(rear))插入一个元素,和dequeue出队它是删除并返回在表的开头(队首(front))的元素,如图是队列的抽象模型。
[img]http://dl2.iteye.com/upload/attachment/0095/0535/7104f728-2fae-34df-a291-6768f79898d6.png[/img]
[b]队列的数组实现[/b]
如同栈的情形一样,对于队列而言任何的表的实现都是合法的,对于每一种操作,链表实现和数组实现都给出快速的常数运行时间。队列的链表实现是简单直接的,下面讨论队列的数组实现。
对于每一个队列数据结构,保留一个数组theArray以及位置front和rear,代表队列的两段。还需要记录实际存在于队列中的元素个数currentSize.
为使一个元素x入队(即执行enqueue),我们让currentSize和rear增1,然后设置theArray[rear] = x.若使元素dequeue,我们设置返回值为theArray[front],并且currentSize减1,然后使front增1.不过这种方式存在一个问题,经过一定次数enqueue以后,队列满了,然而,队列中也许只存在几个元素,因为若干元素可能已经出队了。像栈一样,即使再有许多操作的情况队列也常常不是很大。
简单的解决方法是,只要front和rear大道数组的尾端,就绕道开头。如图是显示某些操作期间的队列情况,这叫做循环数组的实现。如果front和rear增1导致数组越界,那么其值就要重置到数组的第一个位置。
[img]http://dl2.iteye.com/upload/attachment/0095/0537/f521914f-6de1-3dd0-bc6c-cf6aea700866.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0095/0539/644f00f3-adfb-39c9-81c5-530faa49176d.png[/img]
[b]队列代码[/b]
队列的基本操作时enqueue入队,它是在表的末端(队尾(rear))插入一个元素,和dequeue出队它是删除并返回在表的开头(队首(front))的元素,如图是队列的抽象模型。
[img]http://dl2.iteye.com/upload/attachment/0095/0535/7104f728-2fae-34df-a291-6768f79898d6.png[/img]
[b]队列的数组实现[/b]
如同栈的情形一样,对于队列而言任何的表的实现都是合法的,对于每一种操作,链表实现和数组实现都给出快速的常数运行时间。队列的链表实现是简单直接的,下面讨论队列的数组实现。
对于每一个队列数据结构,保留一个数组theArray以及位置front和rear,代表队列的两段。还需要记录实际存在于队列中的元素个数currentSize.
为使一个元素x入队(即执行enqueue),我们让currentSize和rear增1,然后设置theArray[rear] = x.若使元素dequeue,我们设置返回值为theArray[front],并且currentSize减1,然后使front增1.不过这种方式存在一个问题,经过一定次数enqueue以后,队列满了,然而,队列中也许只存在几个元素,因为若干元素可能已经出队了。像栈一样,即使再有许多操作的情况队列也常常不是很大。
简单的解决方法是,只要front和rear大道数组的尾端,就绕道开头。如图是显示某些操作期间的队列情况,这叫做循环数组的实现。如果front和rear增1导致数组越界,那么其值就要重置到数组的第一个位置。
[img]http://dl2.iteye.com/upload/attachment/0095/0537/f521914f-6de1-3dd0-bc6c-cf6aea700866.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0095/0539/644f00f3-adfb-39c9-81c5-530faa49176d.png[/img]
[b]队列代码[/b]
package taxus.list;
public interface Queue {
//返回队列大小
public int getSize();
//判断队列是否为空
public boolean isEmpty();
//元素e入队列
public void enqueue(Object e);
//队首元素出队列
public Object dequeue() throws QueueEmptyException;
//获取队首元素
public Object peek() throws QueueEmptyException;
}
package taxus.list;
public class QueueEmptyException extends Exception {
public QueueEmptyException(String err){
super(err);
}
}
package taxus.list;
public class QueueArray implements Queue {
private static final int CAP = 7; //队列默认大小
private Object[] elements; //数据元素数组
private int capacity; //数组的大小elements.length
private int front; //队首指针,指向队首
private int rear; //队尾指针,指向队尾后一个位置
public QueueArray(){
this(CAP);
}
public QueueArray(int cap) {
capacity = cap + 1;
elements = new Object[capacity];
front = rear = 0;
}
@Override
public int getSize() {
return (rear - front + capacity) % capacity;
}
public boolean isEmpty() {
return front == rear;
}
public void enqueue(Object e) {
if (getSize() == capacity - 1) {
expandSpace();
}
elements[rear] = e;
rear = (rear + 1) % capacity;
}
private void expandSpace(){
Object[] a = new Object[elements.length * 2];
int i = front;
int j = 0;
while (i != rear) {//从front开始到rear前一个存储单元的元素复制数组
a[j++] = elements[i];
i = (i + 1)%capacity;
}
elements = a;
capacity = elements.length;
//重新设置新的队首,队尾指针
front = 0;
rear = j;
}
public Object dequeue() throws QueueEmptyException {
if (isEmpty()) {
throw new QueueEmptyException("错误,队列为空");
}
Object o = elements[front];
elements[front] = null;
front = (front + 1) % capacity;
return o;
}
public Object peek() throws QueueEmptyException {
if (isEmpty()) {
throw new QueueEmptyException("错误,队列为空");
}
return elements[front];
}
}
package taxus.list;
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 e) {
SLNode q = new SLNode(e, null);
rear.setNext(q);
rear = q;
size++;
}
public Object dequeue() throws QueueEmptyException {
if (size < 1) {
throw new QueueEmptyException("错误,队列为空");
}
SLNode p = front.getNext();
front.setNext(p.getNext());
size--;
if (size < 1) front = rear;
return p.getData();
}
public Object peek() throws QueueEmptyException {
if (size < 1) {
throw new QueueEmptyException("错误,队列为空");
}
return front.getNext().getData();
}
}