队列

文章目录

  • 概述
  • ArrayQueue数组队列
  • LoopQueue循环队列
  • LinkedListQueue链式队列

概述

队列也是一种受限制的线性表,大家都知道它的特性是先进先出,根据内部数据结构的不同,可以分为顺序队列链式队列,而对于数组实现的顺序队列,可以通过循环队列的方式提高其效率,而循环队列也是应用最多的一种队列(因为循环队列可以配合CAS实现并发队列)
队列的一个很重要的应用是对于有限资源的排队使用,比如线程池、连接池等的实现

ArrayQueue数组队列

/**
 * @Classname ArrayQueue
 * @Description 基于数组实现的顺序队列
 * @Date 2019/12/15 18:15
 * @Created by SunCheng
 */
public class ArrayQueue<E> {
    // ArrayList是自动扩容的,但是这里我们只是需要它已经实现好的元素操作后的位移
    // 所以这里我们模拟的是一个有固定容量的队列
    private ArrayList<E> data;
    private int capacity;

    public ArrayQueue(int capacity) {
        data = new ArrayList<>(capacity);
        this.capacity = capacity;
    }

    public int getCapacity() {
        return capacity;
    }

    public int getSize(){
        return data.size();
    }

    public boolean isEmpty(){
        return data.isEmpty();
    }

    public void enqueue(E e) {
        if (data.size() >= capacity) {

        }
        data.add(e);
    }

    public E dequeue() {
        if (data.size() <= 0) {
            throw new IllegalArgumentException("队列为空");
        }
        return data.remove(0);
    }

    public E getFront(){
        if (data.size() <= 0) {
            throw new IllegalArgumentException("队列为空");
        }
        return data.get(0);
    }
}

LoopQueue循环队列

循环队列需要注意的有这么几点

  • 判空条件
  • 队列满的条件
  • 数组中会浪费一个空间

代码中已略去一些常规性代码,比如getSize()之类的


/**
 * @Classname LoopQueue
 * @Description 循环队列
 * @Date 2019/12/15 18:19
 * @Created by SunCheng
 */
public class LoopQueue<E> {
    private E[] data;
    private int front,tail;
    private int size;

    public LoopQueue(int capacity) {
        data = (E[]) new Object[capacity+1];
        front = 0;
        tail = 0;
        size = 0;
    }
    
    public void enqueue(E e) {
        // 注意循环队列满的情况
        if ((tail + 1) % data.length == front) {
            resize(getCapacity() << 1);
        }

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

    public E dequeue() {
        if (isEmpty()) {
            throw new IllegalArgumentException("队列为空");
        }
        E ret = data[front];
        data[front] = null;
        front = (front+1)%data.length;
        size--;
        if (size == getCapacity() /4 && getCapacity()/2 != 0) {
            resize(getCapacity() / 2);
        }
        return ret;
    }

    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;
    }
}

LinkedListQueue链式队列

链式队列实现起来就非常简单了

/**
 * @Classname LinkedListQueue
 * @Description 链式队列
 * @Date 2019/12/15 18:16
 * @Created by SunCheng
 */
public class LinkedListQueue<E> {
    private LinkedList<E> data;

    public LinkedListQueue() {
        data = new LinkedList<>();
    }

    public void enqueue(E e) {
        data.addLast(e);
    }

    public E dequeue() {
        return data.removeFirst();
    }
}

你可能感兴趣的:(数据结构与算法)