ADT 介绍
1.数据结构
动画演示:
Tips:
- front 索引始终指向队头元素,而 tail 索引始终指向队尾元素后的空间
- 队列真实容量为
data.length-1
- 队头和队尾再数组中的真实位置为:索引值取模运算结果,模为数组的长度,即
data.length
2.操作集合
- getSize() :获得队列中的元素个数;return类型为int
- getCapacity() :获得队列的容量;return类型为int
- isEmpty() :判断队列是否为空;若空,return true,否则,return false
- enqueue(E element) :入队操作
- dequeue() :出队操作
- getFront() :获取队头元素
代码实现
- Queue.interface
public interface Queue<E> {
int getSize();
boolean isEmpty();
void enqueue(E element);
E dequeue();
E getFront();
}
- LoopQueue.java
public class LoopQueue<E> implements Queue<E> {
final static int DEFAULTCAPACITY = 10;
private E[] data;
private int front, tail;
private int size;
public LoopQueue() {
size = 0;
front = 0;
tail = 0;
ensureCapacity(DEFAULTCAPACITY);
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return front % data.length == tail % data.length;
}
public int getCapacity() {
return data.length - 1;
}
@Override
public void enqueue(E element) {
if(size == getCapacity())
ensureCapacity(data.length * 2);
data[tail % data.length] = element;
tail++;
size++;
}
@Override
public E dequeue() {
if(isEmpty())
throw new IllegalArgumentException("队列为空");
if(size == getCapacity() / 2)
ensureCapacity(data.length / 2);
E ret = data[front % data.length];
front++;
size--;
return ret;
}
private void ensureCapacity(int newCapacity) {
if(newCapacity < size)
return;
E[] old = data;
data = (E[])new Object[newCapacity];
int fro = front;
while(fro % data.length != tail % data.length) {
data[fro % data.length] = old[fro % data.length];
fro++;
}
}
@Override
public E getFront() {
return data[front % data.length];
}
@Override
public String toString() {
String s;
StringBuilder str = new StringBuilder();
str.append("loopQueue:"+"size:"+size+"\tCapacity:"+getCapacity()+'\n');
str.append("front[");
int fro = front;
while(fro % data.length != tail % data.length) {
str.append(data[fro % data.length]);
if(fro % data.length != (tail - 1) % data.length)
str.append(',');
fro++;
}
str.append("]tail");
s = str.toString();
return s;
}
}