循环队列:具有队头指针(front)和队尾指针(rear),指示队列元素所在的位置,避免删除元素时移动大量元素。队列也是一中线性表,只不过它是操作受限的线性表,只能在两端操作,先进先出)。
- 相比普通的队列,元素出队时无需移动大量元素,只需移动头指针。
- 适合处理用户排队等待的情况。
- 队列满的条件 (Rear+1)%n==Front
- 队列空的条件 Rear==Front
-
import java.util.Iterator; public class ArrayLoopQueue<E> implements Queue<E> { //容器 private E[] data; //头尾指针(实际为索引不是真正意义上的指针) private int front; private int rear; 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; size++; rear = ( rear + 1 ) % data.length; } @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; } @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 + 1]; 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(']'); }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; } @Override public Iterator iterator() { return null; } class ArrayLoopQueueI 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; } } private void resize(int newLen) { E[] newData = (E[]) new Object[newLen]; int index = 0; for (int i =0;i!=rear;i = (i+1)%data.length){ newData[index] = data[i]; index++; } data = newData; front = 0; rear = index; } }
双端队列(double ended queue ,deque) 是限定插入和删除操作在表的两端进行的线性表 是一种具有队列和栈的性质的数据结构
-
双端队列空时:front == rear 双端队列满时:(rear + 1) % len == front
-
双端队列大致思想与循环队列一样 无非在队首可添加,在队尾可删除
public interface Deque<E> extends Queue<E> { public void addFirst(E element); public void addLast(E element); public E removeFirst(); public E removeLast(); public E getFirst(); public E getLast(); public int size(); public boolean isEmpty(); public void clear(); }
代码实现:
-
import java.util.Iterator; import p1.接口.Dequeue; public class ArrayDeque<E> implements Dequeue<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("the 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; } @Override public E removeLast() { if (isEmpty()){ throw new IllegalArgumentException("the 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("the queue is null"); } return data[front]; } @Override public E getLast() { if (isEmpty()){ throw new IllegalArgumentException("the 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 peek() { return getFirst(); } @Override public boolean isEmpty() { return size ==0 &&front == rear; } @Override public void clear() { E[] data = (E[]) new Object[DEFAULT_CAPACITY]; size= 0; front =0; rear =0; } @Override public int size() { return size; } @Override public Iterator<E> iterator() { return new ArrayDequeIterator(); } class ArrayDequeIterator implements Iterator<E>{ private int cur = front; @Override public boolean hasNext() { return front!=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(','); }return sb.toString(); } }