美文网首页
队列Queue

队列Queue

作者: GeekAmI | 来源:发表于2018-07-17 13:08 被阅读13次
  1. 接口
public interface Queue<E> {
    int getSize();
    boolean isEmpty();
    void enqueue(E e);
    E dequeue();
    E getFront();
}
  1. 队列-版本1
// [引用动态数组](https://www.jianshu.com/p/5c663b7c7282)
public class ArrayQueue<E> implements Queue<E> {

    private Array<E> array;

    public ArrayQueue() {
        array = new Array<>();
    }

    public ArrayQueue(int capacity) {
        array = new Array<>(capacity);
    }

    @Override
    public int getSize() {
        return array.getSize();
    }

    public int getCapacity() {
        return array.getCapacity();
    }

    @Override
    public boolean isEmpty() {
        return array.isEmpty();
    }

    @Override
    public void enqueue(E e) {
        array.addLast(e);
    }

    @Override
    public E dequeue() {
        return array.removeFirst();
    }

    @Override
    public E getFront() {
        return array.getFirst();
    }

    @Override
    public String toString() {
        StringBuilder ret = new StringBuilder();
        ret.append("Queue front[");
        for (int i = 0; i < getSize(); i++) {
            ret.append(array.get(i));
            if (i != getSize() - 1) {
                ret.append(",");
            }
        }
        ret.append("] tail");
        return ret.toString();
    }

    public static void main(String[] args) {
        ArrayQueue<Integer> arrayQueue = new ArrayQueue<>();
        for (int i = 0; i < 10; i++) {
            arrayQueue.enqueue(i);
            System.out.println(arrayQueue);
            if (i % 3 == 2) {
                arrayQueue.dequeue();
                System.out.println(arrayQueue);
            }
        }
    }
}
  1. 队列-版本2
//循环队列
public class LoopQueue<E> implements Queue<E> {

    private E[] data;
    private int front, tail;
    private int size;

    public LoopQueue() {
        this(10);
    }

    public LoopQueue(int capacity) {
        data = (E[]) new Object[capacity + 1];
        front = 0;
        tail = 0;
        size = 0;
    }

    @Override
    public int getSize() {
        return size;
    }

    public int getCapacity() {
        return data.length - 1;
    }

    @Override
    public boolean isEmpty() {
        return front == tail;
    }

    @Override
    public void enqueue(E e) {
        if ((tail + 1) % data.length == front) {
            resize(getCapacity() * 2);
        }

        data[tail] = e;
        tail = (tail + 1) % data.length;
        size++;
    }

    @Override
    public E dequeue() {
        if (isEmpty()) {
            throw new IllegalArgumentException("cannot dequeue a empty queue!");
        }
        E e = data[front];
        front = (front + 1) % data.length;
        size--;

        if (size == getCapacity() / 4 && getCapacity() / 2 != 0) {
            resize(getCapacity() / 2);
        }
        return e;
    }

    @Override
    public E getFront() {
        if (isEmpty()) {
            throw new IllegalArgumentException("a empty queue!");
        }
        return data[front];
    }

    private void resize(int newCapacity) {
        E[] newData = (E[]) new Object[newCapacity + 1];
        for (int i = 0; i < size; i++) {
            newData[i] = data[(front + i) % data.length];
        }
        data = newData;
        front = 0;
        tail = size;
    }

    @Override
    public String toString() {
        StringBuilder ret = new StringBuilder();
        ret.append("Queue size:" + size + ", capacity:" + getCapacity() + "\n");
        ret.append("front[");
        for (int i = 0; i < size; i++) {
            ret.append(data[(front + i) % data.length]);
            if (i != size - 1) {
                ret.append(",");
            }
        }
        ret.append("] tail");
        return ret.toString();
    }

    public static void main(String[] args) {
        LoopQueue<Integer> arrayQueue = new LoopQueue<>();
        for (int i = 0; i < 10; i++) {
            arrayQueue.enqueue(i);
            System.out.println(arrayQueue);
            if (i % 3 == 2) {
                arrayQueue.dequeue();
                System.out.println(arrayQueue);
            }
        }
    }
}
  1. 性能比较

版本1的dequeue时间复杂度为O(n)

public class Main {

    public static double testQueue(Queue queue, int cnt) {
        long start = System.nanoTime();
        Random random = new Random();
        for (int i = 0; i < cnt; i++) {
            queue.enqueue(random.nextInt(Integer.MAX_VALUE));
        }
        for (int i = 0; i < cnt; i++) {
            queue.dequeue();
        }
        long end = System.nanoTime();
        return (end - start) / 1000000000.0;
    }

    public static void main(String[] args) {

        final int cnt = 100000;

        ArrayQueue<Integer> arrayQueue = new ArrayQueue<>();
        System.out.println("arrayQueue:" + testQueue(arrayQueue, cnt));//arrayQueue:5.962328513

        LoopQueue<Integer> loopQueue = new LoopQueue<>();
        System.out.println("loopQueue:" + testQueue(loopQueue, cnt));//loopQueue:0.027345408
    }
  1. JDK版本
public class ArrayDeque<E> extends AbstractCollection<E>
                           implements Deque<E>, Cloneable, Serializable
{
    /**
     * The array in which the elements of the deque are stored.
     * The capacity of the deque is the length of this array, which is
     * always a power of two. The array is never allowed to become
     * full, except transiently within an addX method where it is
     * resized (see doubleCapacity) immediately upon becoming full,
     * thus avoiding head and tail wrapping around to equal each
     * other.  We also guarantee that all array cells not holding
     * deque elements are always null.
     */
    transient Object[] elements; // non-private to simplify nested class access

    /**
     * The index of the element at the head of the deque (which is the
     * element that would be removed by remove() or pop()); or an
     * arbitrary number equal to tail if the deque is empty.
     */
    transient int head;

    /**
     * The index at which the next element would be added to the tail
     * of the deque (via addLast(E), add(E), or push(E)).
     */
    transient int tail;

    /**
     * The minimum capacity that we'll use for a newly created deque.
     * Must be a power of 2.
     */
    private static final int MIN_INITIAL_CAPACITY = 8;

  ...

相关文章

  • 循环队列的实现方法1

    设:队列长度是QUEUE_LENGTH队列数组是queue[QUEUE_LENGTH]队列头索引是head队列尾索...

  • Java—Queue队列详解

    Queue Queue队列介绍   Queue是用于模拟队列的,啥叫队列?队列就是排队的意思,比如排队结账,先进入...

  • Java—Queue队列详解(Deque/PriorityQue

    Queue Queue队列介绍   Queue是用于模拟队列的,啥叫队列?队列就是排队的意思,比如排队结账,先进入...

  • Queue模块

    一、class Queue.Queue 类 Queue类表示使用FIFO队列 Queue.qsize()返回队列的...

  • 多线程GCD

    1:GCD 创建队列: 串行队列: dispatch_queue_t queue=dispatch_queue_c...

  • 第三周_总结

    队列创建一个队列:queue_obj = queue.Queue(maxsize=30)maxsize :表示允许...

  • GCD 多线程的使用

    1.串行队列 1.1串行队列创建 dispatch_queue_t queue = dispatch_queue_...

  • GCD

    dispatch_queue_t:线程、队列dispatch_queue_create(派发队列)派发队列分为两种...

  • GCD队列queue.h__queue

    队列queue.h方法总览 创建队列(queue)相关方法: 举例说明:

  • GCD相关

    创建队列 dispatch_queue_create("我是串行队列",DISPATCH_QUEUE_SERIAL...

网友评论

      本文标题:队列Queue

      本文链接:https://www.haomeiwen.com/subject/bbpwpftx.html