数据结构学习---队列

像栈一样,队列(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]

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();
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值