java data structure - 6 queue (Queue)

6. Queue

In the data structure of "Queue", the data items are first in first out (FIFO: first in first out). The capacity of the queue can be limited or unlimited.

1. Array-based Queue implementation

In general, for Queue, the core operations are: inserting into the queue (enqueue) and removing it from the queue (dequeue). Because in the queue, the insert operation is inserted to the end of the queue, and the remove operation is to remove the head element of the queue. Therefore, we usually use two variables front (the head of the queue) and rear (the tail of the queue) to record the position of the current element.

Suppose we have a limited-capacity queue for storing letters, as shown in the following figure:

write picture description here

When we want to insert an element, because it is always inserted at the end of the queue, the insertion position is rear+1.

When we want to remove an element, it is removed from the position of the front of the queue head pointer (because the element at the head of the queue is added first, according to the FIFO principle, it should be removed first). When an element is removed, front should be incremented by 1, because after removing an element, the next element becomes the first element.

For example, in the picture above, when 5 elements are removed, the head pointer moves to the position of the letter F, and the first five positions are empty. The tail pointer rear remains unchanged.

Now comes the problem: the positions of several elements removed from the head of the queue are vacant. When we add elements, start from the end of the queue, and when we add to the last position, what should we do? It is unreasonable not to add, after all, the first few positions have been vacated. Our expectation is that when an element at a position is removed, that position can be reused. And what we are talking about here is the limited capacity of data, if we continue to add elements, then we have to add to the head of the queue.

This actually involves the concept of a circular queue. That is, when the tail pointer reaches the last subscript of the array, the next position should be the head of the array.

Therefore, when the tail pointer points to the top of the array, we need to reset the tail pointer (rear) to -1, and then add 1, which is 0, which is the top of the array.

Here is the code implementation:

public class ArrayQueue<V> {
    private Object[] data = null;
    private int front;// 对头指针
    private int rear;// 队尾指针
    private int itemNums;// 队列中当前的元素个数
    private int maxSize;

    public ArrayQueue(Integer maxSize) {
        this.maxSize = maxSize;
        data = new Object[maxSize];
        front = 0;
        rear = -1;
        itemNums = 0;
    }

    /**
     * 插入元素: 1、一般情况下,插入操作是在队列不满的情况下,才调用。因此在插入前,应该先调用isFull
     * 2、在队列中插入元素,正常情况下是在队尾指针(rear)+1的位置上插入,因为我们编写的是循环队列
     * 因此,当队尾指针指向数组顶端的时候,我们要将队尾指针(rear)重置为-1,此时再加1,就是0,也就是数组顶端
     */
    public void insertQueue(V v){
        if (isFull()) {
            throw new IllegalStateException("队列已满");
        }
        if (rear == maxSize - 1) {
            rear = -1;
        }
        data[++rear] = v;
        itemNums++;
    }
    /**
     * 移除元素,返回队头指针front所指向的数据项的值
     * 正常情况下,在remove之前,应该调用isEmpty,如果为空,则不能输入
     */
    public V delQueue(){
        if (isEmpty()) {
            throw new IllegalStateException("队列中没有元素");
        }
        V v = (V)data[front];
        data[front] = null;
        front++;
        if (front == maxSize) {
            front = 0;
        }
        itemNums--;
        return v;
    }
    /**
     * 查看队列首部元素,不移除
     */
    public V showFirst(){
        if (isEmpty()) {
            throw new IllegalStateException("队列中没有元素");
        }
        return (V)data[front];
    }

    public boolean isEmpty() {
        return itemNums == 0;
    }
    public boolean isFull() {
        return itemNums == maxSize;
    }
    public int getMaxSize() {
        return maxSize;
    }
    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }
    @Override
    public String toString() {
        return "ArrayQueue [data=" + Arrays.toString(data) + ", front=" + front
                + ", rear=" + rear + ", itemNums=" + itemNums + ", maxSize="
                + maxSize + "]";
    }
}

2. Queue in Java

A java.util.Queue interface is defined in java, which defines the following methods:

public interface Queue<E> extends Collection<E> {
    //增加一个元索到队尾,如果队列已满,则抛出一个IIIegaISlabEepeplian异常
    boolean add(E e);
    //移除并返回队列头部的元素,如果队列为空,则抛出一个NoSuchElementException异常
    E remove();

    //添加一个元素到队尾,如果队列已满,则返回false
    boolean offer(E e);
    //移除并返问队列头部的元素,如果队列为空,则返回null
    E poll();

    //返回队列头部的元素,如果队列为空,则返回null
    E peek();
    //返回队列头部的元素,如果队列为空,则抛出一个NoSuchElementException异常
    E element();
}

Queue also has a sub-interface BlockingQueue, which mainly defines some methods that should have characteristics in a concurrent environment.

public interface BlockingQueue<E> extends Queue<E> {
...
    //添加一个元素,如果队列满,则阻塞
    void put(E e) throws InterruptedException;
    //移除并返回队列头部的元素,如果队列为空,则阻塞
    E take() throws InterruptedException;
...
}

Java also provides a java.util.Deque double-ended queue (deque, full name double-ended queue), that is, the elements in the queue can be popped from both ends, and the insertion and deletion operations are limited to be performed at both ends of the table.

The Queue we explained earlier is implemented based on arrays. In fact, Queue can also be implemented based on LinkedList. For example, the addFisrt method is always called when adding elements, and the removeLast method is always called when removing elements, which implements FIFO. Therefore, the linked list can realize the function of Queue, which is why we said that the linked list is the most widely used basic data structure in addition to the array. In fact, LinkedList in java implements the Deque interface.

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325488581&siteId=291194637