队列——数组结构实现(普通队列)

亡梦爱人 提交于 2020-01-01 13:03:02

一、队列

1. 队列的概念

  • 队列的核心理念是:先进先出
  • 队列是一种特殊的线性表:它只允许在表的前端(front)进行删除操作,而在表的后端(tail)进行插入操作
  • 队列和栈都是一种操作受限的线性表,其中进行插入操作的端称之为队尾,进行删除操作的端称之为队首

2.队列的属性

  • getFront():获取队首的元素,但不进行出队操作;
  • getSize():获取队列中元素的数量;
  • isEmpty():判断队列是否为空;
  • enqueue():在队尾tail插入元素;
  • dequeue():在队首front删除元素;

上述队列的属性抽象成接口,其代码实现如下:

/**
 * @Author: zjtMeng
 * @Date: 2019/12/22 18:47
 * @Version 1.0
 */
public interface Queue<E> {

    void enqueue(E e);

    E dequeue();

    E getFront();

    int getSize();

    boolean isEmpty();
}

二、普通队列ArrayQueue

  • 普通队列概念是:底层通过数组来实现,且通过调用addLast()实现入队操作,调用removeFirst()实现出队操作;

  • 此部分会用到之前自己封装的数组,其博客地址如下:自己封装的数组Array

2.1基本方法的实现:

  • 队列的有参构造方法和无参构造方法初始化队列的容积,可以直接调用Array的构造方法
    public ArrayQueue(int capacity){
        array =new Array<>(capacity);
    }

    public ArrayQueue(){
        array = new Array<>();
    }
  • 入队操作,通过调用Array中的addLast()方法。由于Array中在设计addLast()方法时,已经考虑了扩容的操作,因此实现队列的入队操作时,不必考虑扩容这部分情况;
    ArrayaddLast()方法和扩容操作代码:
    /**
     * 调用add()方法,实现在所有元素之后添加一个新元素
     */
    public void addLast(E e){
        add(size,e);
    } 

    /**
     * 在index位置上插入元素e
     * @param index
     * @param e
     */
    public void add(int index,E e){
        //判断传入的插入位置参数是否规范以及合乎要求,
        if (index <0 || index> size)
            throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
        //判断当前数组是否已经达到容量了
        if (size == data.length)
        	//调用resize()方法,进行扩容
            resize(2 * data.length);
        //从插入位置开始,后面的所有元素全部向后挪一位
        for (int i=size-1; i>=index; i--)
            data[i+1] = data[i];
        data[index] = e;
        size++;
    }

    /**
     * 扩容
     * @param newCapacity
     */
    private void resize(int newCapacity){
        E[] newData = (E[]) new Object[newCapacity];
        for (int i=0; i<size; i++){
            newData[i] = data[i];
        }
        data = newData;
    }

此处队列调用Array中的addLast()方法,可以实现入队操作;

  • 出队操作,通过调用ArrayremoveFirst()方法。同样的,由于Array中在设计removeFirst()方法时,已经考虑了缩容的操作,因此实现队列的入队操作时,不必考虑扩容这部分情况;
    ArrayremoveFirst()方法和缩容操作代码:
    /**
     * 删除数组最后一个元素,返回删除的元素
     * @return
     */
    public E removeLast(){
        return remove(size-1);
    }
    
    /**
     * 从数组中删除指定位置的元素,并返回删除的元素
     * @param index
     * @return
     */
    public E remove(int index){
        //判断传入的插入位置参数是否规范以及合乎要求,
        if (index <0 || index> size)
            throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
        E ret = data[index];
        for (int i = index; i < size ; i++) {
            data[i] = data[i+1];
        }
        size--;
        //此处将移除位置置为null,是为了 loitering object != memory leak
        data[size] = null;
        //当数组元素减少到一定程度(数组的容量的1/4。而不是1/2)时,数组容量缩小一倍,从而避免数组在1/2容积节点处位置来回扩容缩容操作
        if(size == data.length / 4 && data.length / 2 != 0)
            resize(data.length / 2);
        return ret;
    }

因此此处队列调用Array中的removeFirst()方法,可以实现出队操作;

2.2普通队列的实现

代码如下:

package dataStructure.chapter3;

import dataStructure.chapter1.Array;

/**
 * @Author: zjtMeng
 * @Date: 2019/12/22 18:50
 * @Version 1.0
 */
public class ArrayQueue<E> implements Queue<E> {

    private Array<E> array;

    //有参构造方法
    public ArrayQueue(int capacity){
        array =new Array<>(capacity);
    }

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

    @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 int getSize() {
        return array.getSize();
    }

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

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

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

    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!