ArrayQueue
队列的顺序存储结构本身是由ArrayList实现的
在数据元素入队的时候,相对于在ArrayList表尾添加元素
在数据元素出队的时候,相当于在ArrayList表头删除元素
很明显,入队的时间复杂度O(1),出队的时间复杂度为O(n)
线性表增删数据元素时间复杂符都是O(n),但是这个是按平均算的
队列的出队时间复杂度O(n),可不是按平均算的,因为每次出队都是O(n)
循环队列ArrayLoopQueue
该循环队列的实现思想也是动态数组
但是由于操作元素的特殊性,并不能直接由ArrayList或ArrayQueue实现
所以从头开始定义ArrayLoopQueue
//循环队列
public class ArrayLoopQueue<E> implements Queue<E> {
//存储数据的容器
private E[] data;
//队首指针
private int front;
//队尾指针
private int rear;
//元素的个数(f<r r-f;r<f r+l-f)
private int size;
//默认容量
private static int DEFAULT_CAPACITY = 10;
public ArrayLoopQueue(){
data = (E[]) new Object[DEFAULT_CAPACITY+1];
front = 0;
rear = 0;
size = 0;
}
@Override
public void offer(E element) {
//满了没
if ((rear+1)% data.length==front){
resize(data.length*2-1);
}
data[rear] = element;
rear = (rear+1)% data.length;
size++;
}
@Override
public E poll() {
//空不空
if (isEmpty()){
throw new IllegalArgumentException("queue is null");
}
E ret = data[front];
front = (front+1)% data.length;
size--;
if (size<= (data.length-1)/4 && data.length - 1>DEFAULT_CAPACITY){
resize(data.length/2+1);
}
return ret;
}
private void resize(int newLen) {
E[] newdata = (E[]) new Object[newLen];
int index = 0;
for (int i = front;i!=rear;i= (i+1)%data.length){
newdata[index++] = data[i];
}
data = newdata;
front = 0;
rear = index;
}
@Override
public E peek() {
if (isEmpty()){
throw new IllegalArgumentException("queue is null");
}
return data[front];
}
@Override
public boolean isEmpty() {
return front==rear;
}
@Override
public void clear() {
data = (E[]) new Object[DEFAULT_CAPACITY];
size = 0;
front = 0;
rear = 0;
}
@Override
public int size() {
return size;
}
@Override
public Iterator<E> iterator() {
return null;
}
class ArrayLoopQueueIterator implements Iterator<E>{
private int cur = front;
@Override
public boolean hasNext() {
return cur != rear;
}
@Override
public E next() {
E ret = data[cur];
cur = (cur+1)% data.length;
return ret;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
if (isEmpty()){
sb.append(']');
return sb.toString();
}
for (int i = front;i!=rear;i = (i+1)% data.length){
sb.append(data[i]);
if ((i+1)% data.length==rear){
sb.append(']');
}else {
sb.append(',');
sb.append(' ');
}
}
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (o == null){
return false;
}
if (this == o){
return true;
}
if (o instanceof ArrayLoopQueue){
ArrayLoopQueue<E> other = (ArrayLoopQueue<E>) o;
if (size !=other.size ){
return false;
}
int i =front;
int j = other.front;
while (i != rear){
if (!data[i].equals(other.data[j])){
return false;
}
i = (i+1)%data.length;
j = (j+1)%other.data.length;
}
return true;
}
return false;
}
}
双端队列的定义
双端队列(double ended queue , deque)
是限定插入和删除操作在表的两端进行的线性表
是一种具有队列和栈的性质的数据结构
双端队列空时:front == rear
双端队列满时:(rear + 1) % len == front
Deque双端队列接口的定义
双端队列大致思想与循环队列一样
无非在队首可添加,在队尾可删除
public interface Dequeue <E> extends Queue<E>{
public void addFirst(E element);
public void addList(E element);
public E removeFirst();
public E removeList();
public E getFirst();
public E getList();
}
ArrayDeque类的实现
public class ArrayDeque<E> implements Dequeue<E>, Stack<E> {
private E[] data;
private int front;
private int rear;
private int size;
private static int DEFAULT_CAPACITY = 10;
public ArrayDeque() {
data = (E[]) new Object[DEFAULT_CAPACITY + 1];
front = 0;
rear = 0;
size = 0;
}
@Override
public void addFirst(E element) {
if ((rear + 1) % data.length == front) {
resize(data.length * 2 - 1);
}
front = (front - 1 + data.length) % data.length;
data[front] = element;
size++;
}
private void resize(int newLen) {
E[] newData = (E[]) new Object[newLen];
int index = 0;
for (int i = front; i != rear; i = (i + 1) % data.length) {
newData[index++] = data[i];
}
data = newData;
front = 0;
rear = index;
}
@Override
public void addLast(E element) {
if ((rear + 1) % data.length == front) {
resize(data.length * 2 - 1);
}
data[rear] = element;
rear = (rear + 1) % data.length;
size++;
}
@Override
public E removeFirst() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
E ret = data[front];
front = (front + 1) % data.length;
size--;
if (size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY) {
resize(data.length / 2 + 1);
}
return null;
}
@Override
public E reomveLast() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
rear = (rear - 1 + data.length) % data.length;
E ret = data[rear];
size--;
if (size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY) {
resize(data.length / 2 + 1);
}
return ret;
}
@Override
public E getFirst() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
return data[front];
}
@Override
public E getLast() {
if (isEmpty()) {
throw new IllegalArgumentException("queue is null");
}
return data[(rear - 1 + data.length) % data.length];
}
@Override
public void offer(E element) {
addLast(element);
}
@Override
public E poll() {
return removeFirst();
}
@Override
public E element() {
return getFirst();
}
@Override
public E peek() {
return getLast();
}
@Override
public boolean isEmpty() {
return size == 0 && front == rear;
}
@Override
public void push(E element) {
addLast(element);
}
@Override
public E pop() {
return reomveLast();
}
@Override
public void clear() {
E[] data = (E[]) new Object[DEFAULT_CAPACITY];
front = 0;
rear = 0;
size = 0;
}
@Override
public int size() {
return size;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append('[');
if (isEmpty()) {
sb.append(']');
return sb.toString();
}
for (int i = front; i != rear; i = (i + 1) % data.length) {
sb.append(data[i]);
if ((i + 1) % data.length == rear) {
sb.append(']');
} else {
sb.append(',');
sb.append(' ');
}
}
return sb.toString();
}
@Override
public Iterator<E> iterator() {
return new ArrayDequeIterator();
}
class ArrayDequeIterator implements Iterator<E> {
private int cur = front;
@Override
public boolean hasNext() {
return cur != rear;
}
@Override
public E next() {
E ret = data[cur];
cur = (cur + 1) % data.length;
return ret;
}
}
}