数据结构---队列及简单实现有界队列

队列也是一种特殊的线性表,它只容许在两端进行操做,插入或者取出,不容许操做中间的数据。好比只容许在对头出队,队尾入队。这样就具备先进先出的特性(first in first out-FIFO)。就像排队买东西同样,不容许插队,先排先买。java

队列分为单向队列(有序队列),就是上面所说的排队模型,先进先出的操做,只容许一边进,另外一边出,好比Java中的Queue。另一种就是双端队列,两端均可以进行进出操做。好比java中的Deque数组

既然队列也是线性表的一种,那么实现队列,就能够用数组或者链表来实现。数据结构

若是再细分一点的话,能够看着这俩接口的实现,简单列举几个:并发

PriorityQueue数组实现的有序队列,能够传入一个比较器Comparator实现队列中元素的顺序。。this

ArrayDeque:数组实现的双端队列spa

LinkedList:用链表实现的双端队列3d

Juc并发包下面:指针

ArrayBlockingQueue:数组实现的阻塞队列code

PriorityBlockingQueue:带优先级的阻塞队列blog

LinkedBlockingQueue:链表实现的阻塞队列

能够看出大佬们的命名是很规范的,从类名直接能够看出来这队列的特性以及用什么数据结构实现的。

 

简单用数组实现一个有界队列

 

1.初始化一个数组,这个是头尾都是指向的0

 

 

 

2.插入三个元素,尾移动三位,指向了3

 

 

 3.取出一个元素,头移动一位指向了1

 

 

 咱们会发现头指针走过的数组元素实际上是空出来了的(index = 0)。假设尾指针走到最后了,可是由于咱们有取出元素,前面有空位,因此按理来讲,咱们还能够继续加入元素进去,可是这个时候怎么指针怎么回去呢?能够从新建立一个数组继续开始,这样的话会从新开辟内存空间,并且还须要将现有的数据复制到新的数组中去。若是咱们只想让这个队列保持初始化大小,没有扩容操做,建立一个新的数组去继续放,从空间和时间复杂度来讲都不合适了。这个时候咱们能够经过取模操做,让指针回去,从头开始,既不用开辟新空间,也不用移动数据。这样的话就须要考虑空队列和满队这两个状态的判断。若是满了就没法插入,新数据直接丢弃,按如上逻辑实现一个简单队列。

 

package com.nijunyang.algorithm.queue;

/**
 * Description:
 * Created by nijunyang on 2020/4/4 21:44
 */
public class MyQueue<E> {
    private static final int DEFAULT_SIZE = 10;
    private Object[] elements;
    private int headIndex;
    private int tailIndex;
    private int capacity; //从容量
    private int size;  //已放元素个数

    public MyQueue() {
        this(DEFAULT_SIZE);
    }

    public MyQueue(int capacity) {
        this.elements = new Object[capacity];
        this.capacity = capacity;

    }

    public void push(E e){
        if (isFull()) {  //插入先判断是否满
            return;
        }
        elements[tailIndex] = e;
        size++;
        tailIndex = (tailIndex + 1) % capacity;  //取模实现循环的操做
    }

    public E pop(){
        if(isEmpty()) {  //取元素先判空
            return null;
        }
        E e = (E) elements[headIndex];
        headIndex = (headIndex + 1) % capacity; //取模实现循环的操做
        size--;
        return e;
    }

    public boolean isEmpty(){
        return this.size == 0;
    }

    public int size(){
        return this.size;
    }

    public int getCapacity(){
        return this.capacity;
    }

    public boolean isFull(){
        return this.size == this.capacity;
    }

    public static void main(String[] args) {
        MyQueue<Integer> myQueue = new MyQueue(3);
        myQueue.push(1);
        System.out.println(myQueue.size());
        myQueue.push(2);
        myQueue.push(3);
        System.out.println(myQueue.pop());
        System.out.println(myQueue.size());
        myQueue.push(4);
        myQueue.push(5);
        System.out.println(myQueue.size());

    }


}
相关文章
相关标签/搜索